当我尝试对Java中的notify()进行测试时,发现有些困惑。
在这里,我有两个线程b1和b2,它们具有对另一个线程a的引用。在b1和b2中,它们将调用wait()。在线程a中,它将调用notify()。据我所知,它将调用b1或b2重新开始。当我使用Runnable实现这一点时,确实如此。但是当我使用Thread意识到这一点时,b1和b2都重新开始。有人可以解释吗?
这是代码。
使用Runnable实现:
线程A:
public class threada implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
String name = Thread.currentThread().getName();
System.out.println(name+" started");
synchronized(this){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "end");
notify();
}
}
}
线程B:
public class threadb implements Runnable{
private threada ta;
public threadb(threada a){
ta = a;
}
@Override
public void run() {
// TODO Auto-generated method stub
String name = Thread.currentThread().getName();
System.out.println(name + " started");
synchronized(ta){
try {
ta.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "end");
}
}
}
主要:
public class threadmain {
public static void main(String...args){
threada a = new threada();
threadb b1 = new threadb(a);
threadb b2 = new threadb(a);
new Thread(b1, "b1").start();
new Thread(b2, "b2").start();
new Thread(a, "a").start();
}
}
结果:
b1 started
a started
b2 started
aend
b1end
使用线程实现:
线程A:
public class ThreadA extends Thread{
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name+" started");
synchronized(this){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "end");
notify();
}
}
}
线程B:
public class ThreadB extends Thread{
private ThreadA ta;
public ThreadB(ThreadA a){
ta = a;
}
@Override
public void run() {
// TODO Auto-generated method stub
// super.run();
String name = Thread.currentThread().getName();
System.out.println(name + " started");
synchronized(ta){
try {
ta.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "end");
}
}
}
主要:
public class ThreadMain {
public static void main(String... args) throws InterruptedException {
ThreadA a = new ThreadA();
ThreadB b1 = new ThreadB(a);
ThreadB b2 = new ThreadB(a);
b1.setName("b1");
b2.setName("b2");
b1.start();
b2.start();
Thread.sleep(10);
a.setName("a");
a.start();
}
}
结果:
b1 started
b2 started
a started
aend
b1end
b2end
有趣的是,您的问题的解决方案记录在Thread.join()中。
当线程终止时,this.notifyAll方法被调用
因此,您的一个线程被notify()
调用唤醒,另一个线程被线程A结束并因此notifyAll()
本身发送了一个a 。因此,每次线程死亡时,等待它的所有事物都会唤醒。
对于Runnable
版本,这没有发生,因为等待是链接到Runnable
对象而不是线程。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句