Java中交互方式分為同步和異步兩種:
10余年的豐順網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。成都營銷網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整豐順建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“豐順網(wǎng)站設(shè)計”,“豐順網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
相同的地方:
都屬于交互方式,都是發(fā)送請求。
不同的地方:
同步交互:指發(fā)送一個請求,需要等待返回,然后才能夠發(fā)送下一個請求,有個等待過程;
異步交互:指發(fā)送一個請求,不需要等待返回,隨時可以再發(fā)送下一個請求,即不需要等待。?區(qū)別:一個需要等待,一個不需要等待,在部分情況下,我們的項目開發(fā)中都會優(yōu)先選擇不需要等待的異步交互方式。
擴展資料:
Java,是由Sun Microsystems公司于1995年5月推出的Java程序設(shè)計語言和Java平臺的總稱。用Java實現(xiàn)的HotJava瀏覽器(支持Java applet)顯示了Java的魅力:跨平臺、動態(tài)的Web、Internet計算。從此,Java被廣泛接受并推動了Web的迅速發(fā)展,常用的瀏覽器現(xiàn)均支持Java applet
Java是一種簡單的,面向?qū)ο蟮模植际降?,解釋型的,健壯安全的,結(jié)構(gòu)中立的,可移植的,性能優(yōu)異、多線程的動態(tài)語言。
當(dāng)1995年SUN推出Java語言之后,全世界的目光都被這個神奇的語言所吸引。那么Java到底有何神奇之處呢?
Java語言其實最早誕生于1991年,起初被稱為OAK語言,是SUN公司為一些消費性電子產(chǎn)品而設(shè)計的一個通用環(huán)境。他們最初的目的只是為了開發(fā)一種獨立于平臺的軟件技術(shù),而且在網(wǎng)絡(luò)出現(xiàn)之前,OAK可以說是默默無聞,甚至差點夭折。但是,網(wǎng)絡(luò)的出現(xiàn)改變了OAK的命運。
參考資料:java基礎(chǔ) 百度百科
同步:請求狀態(tài)一致,數(shù)據(jù)狀態(tài)一致;頁面整體刷新,同步在后臺處理結(jié)束后需要重新跳轉(zhuǎn)或轉(zhuǎn)發(fā)處理結(jié)果至前臺,同步比較占用資源,用戶體驗感較差。
異步:請求狀態(tài)不一致,數(shù)據(jù)狀態(tài)一致;頁面局部刷新,異步在后臺處理結(jié)束后不需要跳轉(zhuǎn)或者轉(zhuǎn)發(fā)跳轉(zhuǎn),只需要將處理后的結(jié)果傳送至前臺即可,異步占用資源少,用戶體驗感較好。
聯(lián)系:都是從客戶端或瀏覽器向服務(wù)器發(fā)送請求,然后服務(wù)器接收請求,處理后將結(jié)果響應(yīng)給客戶端前臺。且都可以在請求中攜帶參數(shù)。
1、同步調(diào)用
同步調(diào)用是最基本的調(diào)用方式,對象b中的方法直接調(diào)用對象a的方法,這個時候程序會等待對象a的方法執(zhí)行完返回結(jié)果之后才會繼續(xù)往下走。
代碼如下:
public class A {
public void methodA()
{
System.out.println("this is class A method");
}
}
public class B {
public void methodB()
{
A a = new A();
a.methodA();
System.out.println("this is class B method");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
b.methodB();
}
}
結(jié)果:
this is class A method
this is class B method
2、異步調(diào)用
對象b中的方法調(diào)用對象a的方法,程序并不需要等待對象a的方法返回結(jié)果值,直接繼續(xù)往下走。
代碼如下:
public class A extends Thread{
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("this is class A method");
}
}
public class B {
public void methodB()
{
A a = new A();
a.start();
System.out.println("this is class B method");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
b.methodB();
}
}
結(jié)果:
this is class B method
this is class A method
說明:異步調(diào)用我們通常采用多線程的方法來達到目的
3、回調(diào)
對象a的方法methodA()中調(diào)用對象b的methodB()方法,在對象b的methodB()方法中反過來調(diào)用對象a的callBack()方法,這個callBack()方法稱為回調(diào)函數(shù),這種調(diào)用方法稱為回調(diào)。
代碼如下:
public class A {
public void methodA()
{
B b = new B();
b.methodB(new A());
System.out.println("this is class A method : methodA");
}
public void callBack()
{
System.out.println("this is class A method : callBack");
}
}
public class B {
public void methodB(A a)
{
System.out.println("this is class B method : methodB");
a.callBack();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
a.methodA();
}
}
運行結(jié)果:
this is class B method : methodB
this is class A method : callBack
this is class A method : methodA
注意:這里如果為了代碼的擴展性更好,可以把類A與類B抽象出一個接口出來,然后用實現(xiàn)類去實現(xiàn)著兩個接口,這樣代碼的擴展性會更好,也能滿足更多的業(yè)務(wù)場景。
回調(diào)的核心在于:回調(diào)方將本身對象傳給調(diào)用方,調(diào)用方在本身代碼邏輯執(zhí)行完之后,調(diào)用回調(diào)方的回調(diào)方法。
java同步和異步的區(qū)別如下:
一、根據(jù)情況需要專門的線程方式
如果數(shù)據(jù)將在線程間共享.例如正在寫的數(shù)據(jù)以后可能被另一個線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個線程寫過了,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進行同步存取.
當(dāng)應(yīng)用程序在對象上調(diào)用了一個需要花費很長時間來執(zhí)行的方法,并且不希望讓程序等待方法的返回時,就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率.
二、應(yīng)用不同:
Java同步:
基本概念:每個Object都會有1個鎖.同步就是串行使用一些資源.
(說明:以下有些例子為了突出重點,省略了不必要的代碼.非凡是省掉了一些成員變量,就是需要同步的對象.)
1. 多線程中對共享、可變的數(shù)據(jù)進行同步.
對于函數(shù)中的局部變量沒必要進行同步.
對于不可變數(shù)據(jù),也沒必要進行同步.
多線程中訪問共享可變數(shù)據(jù)才有必要.
2. 單個線程中可以使用synchronized,而且可以嵌套,但無意義.
class Test {
public static void main(String[] args) {
Test t = new Test();
synchronized(t) {
synchronized(t) {
System.out.println("ok!");
}
}
}
}
3. 對象實例的鎖
class Test{
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(this){
//do something here
}
}
}
上面的f1()和f2()效果一致, synchronized取得的鎖都是Test某個實列(this)的鎖.
比如: Test t = new Test();
線程A調(diào)用t.f2()時, 線程B無法進入t.f1(),直到t.f2()結(jié)束.
作用: 多線程中訪問Test的同一個實例的同步方法時會進行同步.
4. class的鎖
class Test{
final static Object o= new Object();
public static synchronized void f1(){
//do something here
}
public static void f2(){
synchronized(Test.class){
//do something here
}
}
public static void f3(){
try {
synchronized (Class.forName("Test")) {
//do something here
}
}
catch (ClassNotFoundException ex) {
}
}
public static void g(){
synchronized(o){
//do something here
}
}
}
上面f1(),f2(),f3(),g()效果一致
f1(),f2(),f3()中synchronized取得的鎖都是Test.class的鎖.
g()是自己產(chǎn)生一個對象o,利用o的鎖做同步
作用: 多線程中訪問此類或此類任一個實例的同步方法時都會同步. singleton模式lazily initializing屬于此類.
5. static method
class Test{
private static int v = 0;
public static void f1(){
//do something, 但函數(shù)中沒用用到v
}
public synchronized static void f2(){
//do something, 函數(shù)中對v進行了讀/寫.
}
}
多線程中使用Test的某個實列時,
(1) f1()是線程安全的,不需要同步
(2) f2()這個靜態(tài)方法中使用了函數(shù)外靜態(tài)變量,所以需要同步.
Java異步:
1、 它要能適應(yīng)不同類型的請求:
本節(jié)用 makeString來說明要求有返回值的請求.用displayString來說明不需要返回值的請求.
2、 要能同時并發(fā)處理多個請求,并能按一定機制調(diào)度:
本節(jié)將用一個隊列來存放請求,所以只能按FIFO機制調(diào)度,你可以改用LinkedList,就可以簡單實現(xiàn)一個優(yōu)先級(優(yōu)先級高的addFirst,低的addLast).
3、有能力將調(diào)用的邊界從線程擴展到機器間(RMI)
4、分離過度耦合,如分離調(diào)用句柄(取貨憑證)和真實數(shù)據(jù)的實現(xiàn).分離調(diào)用和執(zhí)行的過程,可以盡快地將調(diào)返回.
現(xiàn)在看具體的實現(xiàn):
public interface Axman {
Result resultTest(int count,char c);
void noResultTest(String str);
}
這個接口有兩個方法要實現(xiàn),就是有返回值的調(diào)用resultTest和不需要返回值的調(diào)用
noResultTest, 我們把這個接口用一個代理類來實現(xiàn),目的是將方法調(diào)用轉(zhuǎn)化為對象,這樣就可以將多個請求(多個方法調(diào))放到一個容器中緩存起來,然后統(tǒng)一處理,因為 Java不支持方法指針,所以把方法調(diào)用轉(zhuǎn)換為對象,然后在這個對象上統(tǒng)一執(zhí)行它們的方法,不僅可以做到異步處理,而且可以將代表方法調(diào)用的請求對象序列化后通過網(wǎng)絡(luò)傳遞到另一個機器上執(zhí)行(RMI).這也是Java回調(diào)機制最有力的實現(xiàn).
一個簡單的例子.
如果 1: 做A
如果 2: 做B
如果 3: 做C
如果有1000個情況,你不至于用1000個case吧?以后再增加呢?
所以如果C/C++程序員,會這樣實現(xiàn): (c和c++定義結(jié)構(gòu)不同)
type define struct MyStruct{
int mark;
(*fn) ();
} MyList;
然后你可以聲明這個結(jié)構(gòu)數(shù)據(jù):
{1,A,
2,B
3,C
}
做一個循環(huán):
for(i=0;ilength;i++) {
if(數(shù)據(jù)組[i].mark == 傳入的值) (數(shù)據(jù)組[i].*fn)();
}
簡單說c/c++中將要被調(diào)用的涵數(shù)可以被保存起來,然后去訪問,調(diào)用,而Java中,我們無法將一個方法保存,除了直接調(diào)用,所以將要調(diào)用的方法用子類來實現(xiàn),然后把這些子類實例保存起來,然后在這些子類的實現(xiàn)上調(diào)用方法:
interface My{
void test();
}
基本概念:
每個Object都會有1個鎖.
同步就是串行使用一些資源.
(說明:以下有些例子為了突出重點,省略了不必要的代碼.非凡是省掉了一些成員變量,就是需要同步的對象.)
1. 多線程中對共享、可變的數(shù)據(jù)進行同步.
對于函數(shù)中的局部變量沒必要進行同步.
對于不可變數(shù)據(jù),也沒必要進行同步.
多線程中訪問共享可變數(shù)據(jù)才有必要.
2. 單個線程中可以使用synchronized,而且可以嵌套,但無意義.
class Test {
public static void main(String[] args) {
Test t = new Test();
synchronized(t) {
synchronized(t) {
System.out.println("ok!");
}
}
}
}
3. 對象實例的鎖
class Test{
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(this){
//do something here
}
}
}
上面的f1()和f2()效果一致, synchronized取得的鎖都是Test某個實列(this)的鎖.
比如: Test t = new Test();
線程A調(diào)用t.f2()時, 線程B無法進入t.f1(),直到t.f2()結(jié)束.
作用: 多線程中訪問Test的同一個實例的同步方法時會進行同步.
線程,有時被稱為輕量級進程(Lightweight Process,LWP),是程序執(zhí)行流的最小單元。一個標(biāo)準(zhǔn)的線程由線程ID,當(dāng)前指令指針(PC),寄存器集合和堆棧組成。
另外,線程是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。
一個線程可以創(chuàng)建和撤消另一個線程,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運行三種基本狀態(tài)。
就緒狀態(tài)是指線程具備運行的所有條件,邏輯上可以運行,在等待處理機;運行狀態(tài)是指線程占有處理機正在運行;阻塞狀態(tài)是指線程在等待一個事件(如某個信號量),邏輯上不可執(zhí)行。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。
線程是程序中一個單一的順序控制流程。進程內(nèi)一個相對獨立的、可調(diào)度的執(zhí)行單元,是系統(tǒng)獨立調(diào)度和分派CPU的基本單位指運行中的程序的調(diào)度單位。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。
同步就是只能A走完某一段然后停下,讓B開始走一段再停下,再讓A走。。如此往復(fù)。簡單理解就是,必須是一段程序執(zhí)行完后才能執(zhí)行后面的程序。。
異步就是,同一時間可能A和B同時都在往終點趕,此時不存在先后順序,就是說,兩個程序可以同時執(zhí)行,稱為異步。