我制作了这个样本来测试等待/通知功能:
public class WaitingTest implements Runnable {
Thread b = new Thread(this,"query");
int total=0;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait(10);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
@Override
public void run(){
synchronized(b){
for(int i=0; i<1000000000 ; i++){
total += i;
}
}
}
}
问题是,我的输出应该为零,因为我在10ms后通知等待并且我的线程需要比这更长的时间来执行它的工作。所以,我的输出应该为零,而不是它的另一个值。我错过了什么?
编辑:
public class WaitingTest implements Runnable {
Thread b = new Thread(this,"query");
int total=0;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
@Override
public void run(){
synchronized(b){
b.notify();
for(long i=0; i<100000 ; i++){
total += i;
}
}
}
}
答案 0 :(得分:1)
wait()
州的javadoc
此方法使当前线程(称为T)置于其中 等待该对象的设置,然后放弃任何和所有 此对象的同步声明
所以当你这样做时
b.wait(10);
当前线程释放它synchronized
上的b
,因此您的其他线程可以使用来自
run()
方法获取它
b.start();
total
开始增加。当10ms启动时,主线程重新获取b
上的锁(假设run()
完成)并打印出总数。请注意,您的total
很可能会溢出。
答案 1 :(得分:0)
你得到溢出(你不能总结这些1000000000非负的int并将结果存储在int中)。将总计定义为 long 。在 run 方法中完成循环后,也可以调用 b.notify()或 b.notifyAll()
。
另外,将wait(10)改为wait(),这将使打印线程等待
计算线程尽可能多(而不仅仅是10毫秒)
这是进行此测试的正确方法。
关于线程同步部分,我建议您阅读一些内容,例如:这些旧文章。