我尝试使用静态布尔变量来锁定和解锁两个同步线程。 所以我写了下面的代码:
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();
}
}
可能我做得不对,因为只有一个线程正在打印&#34; mychar&#34;而另一个线程只是进入wait()而不是在我执行notifyAll()时唤醒。 我认为这可以是为整个类使用静态布尔变量的好方法,而不是每次更改它并调用notifyAll()来检查其他对象中的这个标志......
输出示例:
Thread-0 is runing
Thread-1 is runing
Thread-1 is waiting
##########
##########
##########
##########
##########
##########
##########
##########
##########
##########
答案 0 :(得分:4)
为什么它不起作用
notify()
和wait()
使用&#34;监视器&#34;它们被调用的对象在您的情况下,这是this
,即正在运行的Thread1
的特定实例。
所以,当Thread-0
运行时:
lock
false
notifyAll()
上调用this
(本身就是Thread-0
)。 Thread-1
运行:
lock
true
wait()
上调用this
(本身就是Thread-1
)由于Thread-0
在notifyAll()
(本身)上调用this
,Thread-1
在wait()
调用this
(这是本身),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
}
}
答案 1 :(得分:1)
很抱歉,但这会带来负值,因为它没有任何保证,只会给人一种安全感。这有几个问题:
notifyAll()
唤醒在对象实例上等待的所有线程。由于每个线程都在等待自己作为监视器,因此它们不会被唤醒。 Java中有很多好的锁定机制 - 尝试并发包中的那些(虽然在你的情况下,一个简单的同步块就足够了)。如果你坚持使用布尔值来锁定,你需要:
AtomicBoolean
作为你的信号(只要你不改变它并保证可见性,非最终会很好)compareAndSet
作为循环/锁定条件,以便访问是原子的。Wait()
上的AtomicBoolean
,以便线程共享他们正在等待的监视器(以及notifyAll()
)。答案 2 :(得分:0)
您可以使用更简单的方法来同步线程。
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);
}
}
}
}