等待不是超时

时间:2013-12-15 18:57:46

标签: java multithreading concurrency wait notify

我制作了这个样本来测试等待/通知功能:

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;
                }

            }
        }
    }

2 个答案:

答案 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毫秒) 这是进行此测试的正确方法。

关于线程同步部分,我建议您阅读一些内容,例如:这些旧文章。

http://www.javaworld.com/article/2074217/java-concurrency/java-101--understanding-java-threads--part-1--introducing-threads-and-runnables.html

http://www.javaworld.com/article/2074318/java-concurrency/java-101--understanding-java-threads--part-2--thread-synchronization.html

http://www.javaworld.com/article/2071214/java-concurrency/java-101--understanding-java-threads--part-3--thread-scheduling-and-wait-notify.html

http://www.javaworld.com/article/2074481/java-concurrency/java-101--understanding-java-threads--part-4---thread-groups--volatility--and-threa.html