仅在每个对象实例上创建Thread的实例

时间:2018-04-27 09:16:25

标签: java multithreading

public class AsyncCommand {
    public int i=1;
    public Object lock=new Object();

    public void execute() {
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {

                while(true){
                    synchronized (lock) {
                        try {
                            if(i%2 ==0){
                                lock.wait();
                            }

                            System.out.println(i);
                            Thread.sleep(1000);
                            i++;
                            lock.notify();

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }


                }


            }
        });
        Thread t1=new Thread(new Runnable() {

            @Override
            public void run() {
                while(true){
                    synchronized (lock) {
                        try {
                            if(i%2 !=0){
                                lock.wait();
                            }
                            System.out.println(i);
                            Thread.sleep(1000);
                            i++;
                            lock.notify();

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }



            }
        });
        t.start();
        t1.start();
    }
}

公共课测试{

public static void main(String[] args) {
    AsyncCommand a=new AsyncCommand();
    //AsyncCommand a1=new AsyncCommand();
    a.execute();
    a.execute();
    a.execute();
    //a1.execute();
    //a1.execute();
}

}

实际输出: 1 2 3 4 五 。
预期产量: 1 1 1 2 2 2 3 3 3 。

为什么只为第一次调用execute()创建线程。之后没有创建线程。对于每次调用execute方法,都应该创建两个新线程。

2 个答案:

答案 0 :(得分:1)

正在创建多个线程 。但它们都使用相同的i,因为只有一个AsyncCommand实例,而i是一个实例变量。所以你只能看到提升值。

您可以通过更改

来判断多个线程正在运行
System.out.println(i);

System.out.println(Thread.currentThread().getName() + ": " + i);

在两个地方输出i。然后你会看到

Thread-0: 1
Thread-5: 2
Thread-4: 3
Thread-3: 4
Thread-2: 5
Thread-1: 6
Thread-2: 7
...

......或类似的。

答案 1 :(得分:0)

实际上创建了多个线程。但问题是,你在每个创建的线程中使用了相同实例的变量'i'。

因此,当一个线程处于等待状态时,另一个线程增加“i”的值。因此,如果您需要所需的结果,请为每个execute()调用创建并使用AsyncCommand类的新实例。

Test.java

public class Test {
   public static void main(String[] args) {
       AsyncCommand a1=new AsyncCommand();
       AsyncCommand a2=new AsyncCommand();
       AsyncCommand a3=new AsyncCommand();
       a1.execute();
       a2.execute();
       a3.execute();
   }