![](/img/trans.png)
[英]Can a thread acquire a lock on a instance of a class,when other thread is executing a static synchronized method of this class?
[英]can I use static boolean variable as a lock for a synchronized thread?
我試圖使用靜態布爾變量來鎖定和解鎖兩個同步的線程。 所以我寫了下面的代碼:
public class Main {
public static void main(String[] args){
//MyObject lock = new MyObject();
Thread1 t1 = new Thread1(100,'#');
Thread1 t2 = new Thread1(100,'*');
t1.start();
t2.start();
}
}
public class Thread1 extends Thread {
public static boolean lock;
int myNum;
char myChar;
public Thread1(int num, char c){
myNum = num;
myChar = c;
lock = false;
}
public synchronized void run(){
System.out.println(getName() + " is runing");
while (Thread1.lock == true){
System.out.println(getName() + " is waiting");
try{wait();}
catch(InterruptedException e){}
}
Thread1.lock = true;
for(int i = 0; i<myNum; i++){
if(i%10==0)
System.out.println("");
System.out.print(myChar);
}
Thread1.lock = false;
notifyAll();
}
}
可能我做得不對,因為只有一個線程正在打印“mychar”而另一個線程只是進入wait()並且在我執行notifyAll()時沒有醒來。 我認為這可以是一個很好的方法來為整個類使用靜態布爾變量,而不是每次更改它並調用notifyAll()來檢查其他對象中的這個標志...
輸出示例:
Thread-0 is runing
Thread-1 is runing
Thread-1 is waiting
##########
##########
##########
##########
##########
##########
##########
##########
##########
##########
為什么它不起作用
notify()
和wait()
使用它們被調用的對象的“監視器”。 在您的情況下,就是this
,正在運行的Thread1
的特定實例。
所以,當Thread-0
運行時:
lock
false
notifyAll()
對this
(它本身, Thread-0
)。 Thread-1
運行:
lock
true
wait()
對this
(它本身, Thread-1
) 由於Thread-0
this
調用notifyAll()
(它本身),並且Thread-1
this
調用wait()
(它本身 ),因此Thread-1
正在等待一個不同於Thread-0
通知的監視器,所以它從未發布過。
解
如果您的計划是讓代碼按順序運行,請使用:
public class Thread1 extends Thread {
private static final Object lock = new Object();
public void run(){
// non-sequential code
System.out.println(getName() + " is running");
synchronized (lock) {
// this code will be run sequentially by one thread at a time
}
// non-sequential code
}
}
對不起,但這提供了負值,因為它沒有任何保證,只會給人一種安全感。 這有幾個問題:
notifyAll()
喚醒等待對象實例的所有線程。 由於每個線程都在等待自己作為監視器,因此它們不會被喚醒。 Java中有很多好的鎖定機制 - 嘗試並發包中的那些(雖然在你的情況下,一個簡單的同步塊就足夠了)。 如果你堅持使用布爾值來鎖定,你需要:
AtomicBoolean
一個靜態的最終 AtomicBoolean
(只要你不改變它並保證可見性,非final就可以了) compareAndSet
作為循環/鎖定條件,以便訪問是原子的。 AtomicBoolean
上Wait()
,以便線程共享它們正在等待的監視器(以及它上面的notifyAll()
)。 您可以使用更簡單的方法來同步線程。
class Thread1 extends Thread {
private static final Object lock = new Object();
int myNum;
char myChar;
public Thread1(int num, char c){
myNum = num;
myChar = c;
}
public void run(){
System.out.println(getName() + " is runing");
synchronized(lock) {
for(int i = 0; i<myNum; i++){
if(i%10==0)
System.out.println("");
System.out.print(myChar);
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.