运行Thread对象的多个实例

时间:2014-03-04 16:40:33

标签: java multithreading

我有一个线程对象 - ThreadB,它添加数字1 - 100.我创建它的2个实例 - b& C。

启动2个线程(不同的实例)并运行它。

结果:

    Waiting for b to complete...
    Total is: 4950
    Waiting for c to complete...

为什么我的第二个实例没有完成......

Java代码:

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB();
        ThreadB c = new ThreadB();
        b.start();
        c.start();

        synchronized(b){
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + b.total);
        }

        synchronized(c){
            try{
                System.out.println("Waiting for c to complete...");
                c.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + c.total);
        }
    }
}

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

因为第二个ThreadB在第一个ThreadB上同步的块中完成。然后等待你的第二个ThreadB,但是notify()已经发生了,所以你将永远等待。

请注意,这不保证,您的程序有时可能有效。

在ThreadB类中放入一些print语句来测试这个理论。

答案 1 :(得分:1)

如果您只想等待两个线程完成,则应使用专门为此设计的Thread join方法。

它还使用了waitnotify(或更确切地说notifyAll)。

您的代码也会更清晰:

System.out.println("Waiting for b to complete...");
b.join();
System.out.println("b completed.");

System.out.println("Waiting for c to complete...");
c.join();
System.out.println("c completed.");

System.out.println("b's total is " + b.total");
System.out.println("c's total is " + c.total");

答案 2 :(得分:0)

这不是解决问题的正确方法。您正在尝试序列化两个独立的线程,这是没有意义的。

如果您的唯一目的是向用户提供一些反馈,您可以让每个线程在退出之前通知用户它已终止其工作:

    class ThreadB extends Thread{
    String name;
    int total;

    public ThreadB(String name){
        this.name = name;
    }

    @Override
    public void run(){
        System.out.println("Waiting for "+name+" to complete...");
        for(int i=0; i<100 ; i++){
            total += i;
        }
        System.out.println(name+" completed. Total is "+total);

    }
}

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB("b");
        ThreadB c = new ThreadB("c");
        b.start();
        c.start();
    }
}

否则,如果您需要在所有线程完成后执行某些操作,则需要在共享对象上进行同步,而不是在线程上进行同步。