① java如何在for循環內方法同步
豈止2次啊。sunchronized就是一把價格昂貴的鎖,防止你用的時候別人去用了。
② java常見的幾種調用機制(同步調用,非同步調用
1、同步調用
同步調用是最基本的調用方式,對象b中的方法直接調用對象a的方法,這個時候程序會等待對象a的方法執行完返回結果之後才會繼續往下走。
代碼如下:
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();
}
}
結果:
this is class A method
this is class B method
2、非同步調用
對象b中的方法調用對象a的方法,程序並不需要等待對象a的方法返回結果值,直接繼續往下走。
代碼如下:
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();
}
}
結果:
this is class B method
this is class A method
說明:非同步調用我們通常採用多線程的方法來達到目的
3、回調
對象a的方法methodA()中調用對象b的methodB()方法,在對象b的methodB()方法中反過來調用對象a的callBack()方法,這個callBack()方法稱為回調函數,這種調用方法稱為回調。
代碼如下:
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();
}
}
運行結果:
this is class B method : methodB
this is class A method : callBack
this is class A method : methodA
注意:這里如果為了代碼的擴展性更好,可以把類A與類B抽象出一個介面出來,然後用實現類去實現著兩個介面,這樣代碼的擴展性會更好,也能滿足更多的業務場景。
回調的核心在於:回調方將本身對象傳給調用方,調用方在本身代碼邏輯執行完之後,調用回調方的回調方法。
③ JAVA多線程同步方式哪些
1 wait方法:
該方法屬於Object的方法,wait方法的作用是使得當前調用wait方法所在部分(代碼塊)的線程停止執行,並釋放當前獲得的調用wait所在的代碼塊的鎖,並在其他線程調用notify或者notifyAll方法時恢復到競爭鎖狀態(一旦獲得鎖就恢復執行)。
調用wait方法需要注意幾點:
第一點:wait被調用的時候必須在擁有鎖(即synchronized修飾的)的代碼塊中。
第二點:恢復執行後,從wait的下一條語句開始執行,因而wait方法總是應當在while循環中調用,以免出現恢復執行後繼續執行的條件不滿足卻繼續執行的情況。
第三點:若wait方法參數中帶時間,則除了notify和notifyAll被調用能激活處於wait狀態(等待狀態)的線程進入鎖競爭外,在其他線程中interrupt它或者參數時間到了之後,該線程也將被激活到競爭狀態。
第四點:wait方法被調用的線程必須獲得之前執行到wait時釋放掉的鎖重新獲得才能夠恢復執行。
2 notify方法和notifyAll方法:
notify方法通知調用了wait方法,但是尚未激活的一個線程進入線程調度隊列(即進入鎖競爭),注意不是立即執行。並且具體是哪一個線程不能保證。另外一點就是被喚醒的這個線程一定是在等待wait所釋放的鎖。
notifyAll方法則喚醒所有調用了wait方法,尚未激活的進程進入競爭隊列。
3 synchronized關鍵字:
第一點:synchronized用來標識一個普通方法時,表示一個線程要執行該方法,必須取得該方法所在的對象的鎖。
第二點:synchronized用來標識一個靜態方法時,表示一個線程要執行該方法,必須獲得該方法所在的類的類鎖。
第三點:synchronized修飾一個代碼塊。類似這樣:synchronized(obj) { //code.... }。表示一個線程要執行該代碼塊,必須獲得obj的鎖。這樣做的目的是減小鎖的粒度,保證當不同塊所需的鎖不沖突時不用對整個對象加鎖。利用零長度的byte數組對象做obj非常經濟。
④ 初學Java多線程:使用Synchronized塊同步方法
synchronized關鍵字有兩種用法 第一種就是在《使用Synchronized關鍵字同步類方法》一文中所介紹的直接用在方法的定義中 另外一種就是synchronized塊 我們不僅可以通過synchronized塊來同步一個對象變數 也可以使用synchronized塊來同步類中的靜態方法和非靜態方法
synchronized塊的語法如下
public void method()
{
… …
synchronized(表達式)
{
… …
}
}
一 非靜態類方法的同步
從《使用Synchronized關鍵字同步類方法》一文中我們知道使用synchronized關鍵字來定義方法就會鎖定類中所有使用synchronzied關鍵字定義的靜態方法或非靜態方法 但這並不好理解 而如果使用synchronized塊來達到同樣的效果 就不難理解為什麼會產生這種效果了 如果想使用synchronized塊來鎖定類中所有的同步非靜態方法 需要使用this做為synchronized塊的參數傳入synchronized塊國 代碼如下
通過synchronized塊同步非靜態方法
public class SyncBlock
{
public void method ()
{
synchronized(this) // 相當於對method 方法使用synchronized關鍵字
{
… …
}
}
public void method ()
{
synchronized(this) // 相當於對method 方法使用synchronized關鍵字
{
… …
}
}
public synchronized void method ()
{
… …
}
}
在上面的代碼中的method 和method 方法中使用了synchronized塊 而第 行的method 方法仍然使用synchronized關鍵字來定義方法 在使用同一個SyncBlock類實例時 這三個方法只要有一個正在執行 其他兩個方法就會因未獲得同步鎖而被阻塞 在使用synchronized塊時要想達到和synchronized關鍵字同樣的效果 必須將所有的代碼都寫在synchronized塊中 否則 將無法使當前方法中的所有代碼和其他的方法同步
除了使用this做為synchronized塊的參數外 還可以使用SyncBlock this作為synchronized塊的參數來達到同樣的效果
在內類(InnerClass)的方法中使用synchronized塊來時 this只表示內類 和外類(OuterClass)沒有關系 但內類的非靜態方法可以和外類的非靜態方法同步 如在內類InnerClass中加一個method 方法 並使method 方法和SyncBlock的三個方法同步 代碼如下
使內類的非靜態方法和外類的非靜態方法同步
public class SyncBlock
{
… …
class InnerClass
{
public void method ()
{
synchronized(SyncBlock this)
{
… …
}
}
}
… …
}
在上面SyncBlock類的新版本中 InnerClass類的method 方法和SyncBlock類的其他三個方法同步 因此 method method method 和method 四個方法在同一時間只能有一個方法執行
Synchronized塊不管是正常執行完 還是因為程序出錯而異常退出synchronized塊 當前的synchronized塊所持有的同步鎖都會自動釋放 因此 在使用synchronized塊時不必擔心同步鎖的釋放問題
二 靜態類方法的同步
由於在調用靜態方法時 對象實例不一定被創建 因此 就不能使用this來同步靜態方法 而必須使用Class對象來同步靜態方法 代碼如下
通過synchronized塊同步靜態方法
public class StaticSyncBlock
{
public static void method ()
{
synchronized(StaticSyncBlock class)
{
… …
}
}
public static synchronized void method ()
{
… …
}
}
在同步靜態方法時可以使用類的靜態欄位class來得到Class對象 在上例中method 和method 方法同時只能有一個方法執行 除了使用class欄位得到Class對象外 還可以使用實例的getClass方法來得到Class對象 上例中的代碼可以修改如下
使用getClass方法得到Class對象
public class StaticSyncBlock
{
public static StaticSyncBlock instance;
public StaticSyncBlock()
{
instance = this;
}
public static void method ()
{
synchronized(instance getClass())
{
}
}
}
在上面代碼中通過一個public的靜態instance得到一個StaticSyncBlock類的實例 並通過這個實例的getClass方法得到了Class對象(一個類的所有實例通過getClass方法得到的都是同一個Class對象 因此 調用任何一個實例的getClass方法都可以) 我們還可以通過Class對象使不同類的靜態方法同步 如Test類的靜態方法method和StaticSyncBlock類的兩個靜態方法同步 代碼如下
Test類的method方法和StaticSyncBlock類的method method 方法同步
public class Test
{
public static void method()
{
synchronized(StaticSyncBlock class)
{
}
}
}
lishixin/Article/program/Java/gj/201311/27374