本文目錄一覽:
java 異步調用方法
1. 使用wait和notify方法
這個方法其實是利用了鎖機制,直接貼代碼:
public class Demo1 extends BaseDemo{ private final Object lock = new Object(); @Override public void callback(long response) { System.out.println(“得到結果”); System.out.println(response); System.out.println(“調用結束”); synchronized (lock) { lock.notifyAll(); } } public static void main(String[] args) { Demo1 demo1 = new Demo1(); demo1.call(); synchronized (demo1.lock){ try { demo1.lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“主線程內容”); } }
可以看到在發起調用後,主線程利用wait進行阻塞,等待回調中調用notify或者notifyAll方法來進行喚醒。注意,和大家認知的一樣,這裡wait和notify都是需要先獲得對象的鎖的。在主線程中最後我們打印了一個內容,這也是用來驗證實驗結果的,如果沒有wait和notify,主線程內容會緊隨調用內容立刻打印;而像我們上面的代碼,主線程內容會一直等待回調函數調用結束才會進行打印。
沒有使用同步操作的情況下,打印結果:發起調用 調用返回 主線程內容 得到結果 1 調用結束
而使用了同步操作後:
發起調用 調用返回 得到結果 9 調用結束 主線程內容2. 使用條件鎖
和方法一的原理類似:
public class Demo2 extends BaseDemo { private final Lock lock = new ReentrantLock(); private final Condition con = lock.newCondition(); @Override public void callback(long response) { System.out.println(“得到結果”); System.out.println(response); System.out.println(“調用結束”); lock.lock(); try { con.signal(); }finally { lock.unlock(); } } public static void main(String[] args) { Demo2 demo2 = new Demo2(); demo2.call(); demo2.lock.lock(); try { demo2.con.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { demo2.lock.unlock(); } System.out.println(“主線程內容”); } }
基本上和方法一沒什麼區別,只是這裡使用了條件鎖,兩者的鎖機制有所不同。
java同步和異步的區別
java同步和異步的區別如下:
一、根據情況需要專門的線程方式
如果數據將在線程間共享.例如正在寫的數據以後可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取.
當應用程序在對象上調用了一個需要花費很長時間來執行的方法,並且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下採用異步途徑往往更有效率.
二、應用不同:
Java同步:
基本概念:每個Object都會有1個鎖.同步就是串行使用一些資源.
(說明:以下有些例子為了突出重點,省略了不必要的代碼.非凡是省掉了一些成員變量,就是需要同步的對象.)
1. 多線程中對共享、可變的數據進行同步.
對於函數中的局部變量沒必要進行同步.
對於不可變數據,也沒必要進行同步.
多線程中訪問共享可變數據才有必要.
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調用t.f2()時, 線程B無法進入t.f1(),直到t.f2()結束.
作用: 多線程中訪問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()是自己產生一個對象o,利用o的鎖做同步
作用: 多線程中訪問此類或此類任一個實例的同步方法時都會同步. singleton模式lazily initializing屬於此類.
5. static method
class Test{
private static int v = 0;
public static void f1(){
//do something, 但函數中沒用用到v
}
public synchronized static void f2(){
//do something, 函數中對v進行了讀/寫.
}
}
多線程中使用Test的某個實列時,
(1) f1()是線程安全的,不需要同步
(2) f2()這個靜態方法中使用了函數外靜態變量,所以需要同步.
Java異步:
1、 它要能適應不同類型的請求:
本節用 makeString來說明要求有返回值的請求.用displayString來說明不需要返回值的請求.
2、 要能同時並發處理多個請求,並能按一定機制調度:
本節將用一個隊列來存放請求,所以只能按FIFO機制調度,你可以改用LinkedList,就可以簡單實現一個優先級(優先級高的addFirst,低的addLast).
3、有能力將調用的邊界從線程擴展到機器間(RMI)
4、分離過度耦合,如分離調用句柄(取貨憑證)和真實數據的實現.分離調用和執行的過程,可以儘快地將調返回.
現在看具體的實現:
public interface Axman {
Result resultTest(int count,char c);
void noResultTest(String str);
}
這個接口有兩個方法要實現,就是有返回值的調用resultTest和不需要返回值的調用
noResultTest, 我們把這個接口用一個代理類來實現,目的是將方法調用轉化為對象,這樣就可以將多個請求(多個方法調)放到一個容器中緩存起來,然後統一處理,因為 Java不支持方法指針,所以把方法調用轉換為對象,然後在這個對象上統一執行它們的方法,不僅可以做到異步處理,而且可以將代表方法調用的請求對象序列化後通過網絡傳遞到另一個機器上執行(RMI).這也是Java回調機制最有力的實現.
一個簡單的例子.
如果 1: 做A
如果 2: 做B
如果 3: 做C
如果有1000個情況,你不至於用1000個case吧?以後再增加呢?
所以如果C/C++程序員,會這樣實現: (c和c++定義結構不同)
type define struct MyStruct{
int mark;
(*fn) ();
} MyList;
然後你可以聲明這個結構數據:
{1,A,
2,B
3,C
}
做一個循環:
for(i=0;ilength;i++) {
if(數據組[i].mark == 傳入的值) (數據組[i].*fn)();
}
簡單說c/c++中將要被調用的涵數可以被保存起來,然後去訪問,調用,而Java中,我們無法將一個方法保存,除了直接調用,所以將要調用的方法用子類來實現,然後把這些子類實例保存起來,然後在這些子類的實現上調用方法:
interface My{
void test();
}
java異步方法什麼意思
在JAVA平台,實現異步調用的角色有如下三個角色:調用者,取貨憑證,真實數據
異步調用就是:一個調用者在調用耗時操作,不能立即返回數據時,先返回一個取貨憑證.然後在過一斷時間後憑取貨憑證來獲取真正的數據.
如果數據將在線程間共享。例如正在寫的數據以後可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。當應用程序在對象上調用了一個需要花費很長時間來執行的方法,並且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下採用異步途徑往往更有效率
只有一個馬桶
很多人上廁所
要排隊
這叫同步迅雷一次可以下載很多東西
這叫異步
java中同步和異步有什麼異同?
Java中交互方式分為同步和異步兩種:
相同的地方:
都屬於交互方式,都是發送請求。
不同的地方:
同步交互:指發送一個請求,需要等待返回,然後才能夠發送下一個請求,有個等待過程;
異步交互:指發送一個請求,不需要等待返回,隨時可以再發送下一個請求,即不需要等待。 區別:一個需要等待,一個不需要等待,在部分情況下,我們的項目開發中都會優先選擇不需要等待的異步交互方式。
擴展資料:
Java,是由Sun Microsystems公司於1995年5月推出的Java程序設計語言和Java平台的總稱。用Java實現的HotJava瀏覽器(支持Java applet)顯示了Java的魅力:跨平台、動態的Web、Internet計算。從此,Java被廣泛接受並推動了Web的迅速發展,常用的瀏覽器現均支持Java applet
Java是一種簡單的,面向對象的,分佈式的,解釋型的,健壯安全的,結構中立的,可移植的,性能優異、多線程的動態語言。
當1995年SUN推出Java語言之後,全世界的目光都被這個神奇的語言所吸引。那麼Java到底有何神奇之處呢?
Java語言其實最早誕生於1991年,起初被稱為OAK語言,是SUN公司為一些消費性電子產品而設計的一個通用環境。他們最初的目的只是為了開發一種獨立於平台的軟件技術,而且在網絡出現之前,OAK可以說是默默無聞,甚至差點夭折。但是,網絡的出現改變了OAK的命運。
參考資料:java基礎 百度百科
Java中的線程同步與異步如何理解?
線程,有時被稱為輕量級進程(Lightweight Process,LWP),是程序執行流的最小單元。一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組成。
另外,線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。
一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以並發執行。由於線程之間的相互制約,致使線程在運行中呈現出間斷性。線程也有就緒、阻塞和運行三種基本狀態。
就緒狀態是指線程具備運行的所有條件,邏輯上可以運行,在等待處理機;運行狀態是指線程佔有處理機正在運行;阻塞狀態是指線程在等待一個事件(如某個信號量),邏輯上不可執行。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。
線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位指運行中的程序的調度單位。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。
同步就是只能A走完某一段然後停下,讓B開始走一段再停下,再讓A走。。如此往複。簡單理解就是,必須是一段程序執行完後才能執行後面的程序。。
異步就是,同一時間可能A和B同時都在往終點趕,此時不存在先後順序,就是說,兩個程序可以同時執行,稱為異步。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/293060.html