所有值仅通过一个线程打印

时间:2019-05-24 20:27:13

标签: java multithreading

正在等待再次启动(处于等待状态)的线程0即使在被另一个线程通知后也没有启动。有人可以帮我处理下面的代码。

尝试使用两个线程(线程0,线程1)打印数字,但是一旦线程进入等待状态,即使在调用另一个线程的通知之后,它也不会启动

package com.chan.newFeature;
class ValuePrinter  implements  Runnable
{

    private volatile  static int maxValue=1;
    private int reminder;
    public ValuePrinter(int reminder) {
        this.reminder = reminder;
    }
    public ValuePrinter() {

    }

    @Override
    public void run() {

        while(maxValue<20){
            synchronized (this){
             //   System.out.println("maxValue "+maxValue);
            /*if (maxValue%2==0)
                printEven();
            else
                printOdd();*/
            if (maxValue%2==reminder){
                try {
                   System.out.println("Inside Synchronized Context Thread.currentThread().getName() :"+Thread.currentThread().getName() +":"+maxValue);
                   this.wait();
                    System.out.println("Inside Synchronized Context after wait Thread.currentThread().getName() :"+Thread.currentThread().getName() +":"+maxValue);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
           //     System.out.println("Thread.currentThread().getName()"+Thread.currentThread().getName());
                System.out.println("Thread.currentThread().getName() :"+Thread.currentThread().getName() +":"+maxValue+":"+reminder);
                this.notify();
                System.out.println("Thread.currentThread().getName() :");
                maxValue=maxValue+1;
            }
        }
    }


}







public class OddEvenExample {


    public static void main(String[] args) {
        ValuePrinter valuePrinter=new ValuePrinter(2);
        ValuePrinter valuePrinter2=new ValuePrinter(1);
        Thread t1=new Thread(valuePrinter);
        Thread t2=new Thread(valuePrinter2);
        t1.start();
        t2.start();
    }
}

Thread.currentThread().getName() :Thread-0:1:2
Inside Synchronized Context Thread.currentThread().getName() :Thread-1:1
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:2:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:3:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:4:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:5:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:6:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:7:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:8:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:9:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:10:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:11:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:12:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:13:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:14:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:15:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:16:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:17:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:18:2
Thread.currentThread().getName() :
Thread.currentThread().getName() :Thread-0:19:2
Thread.currentThread().getName() :

1 个答案:

答案 0 :(得分:0)

我编辑了答案:“用notifyAll()替换notify()”不是正确的答案,但是问题出在这里:Why can't I use notifyAll() to wake up a waiting thread?您正在创建两个独立且不在同一锁中的对象。简而言之,您的通知仅引用该特定对象线程。

在这里,我得到了您想要的答案:

static Object lock = new Object();

@Override
public void run() {

     while(maxValue<50){
            synchronized (lock){
             //   System.out.println("maxValue "+maxValue);
            /*if (maxValue%2==0)
                printEven();
            else
                printOdd();*/
            if (maxValue%2==reminder){
                try {
                   System.out.println("Inside Synchronized Context Thread.currentThread().getName() :"+Thread.currentThread().getName() +":"+maxValue);
                   lock.wait();
                   System.out.println("Inside Synchronized Context after wait Thread.currentThread().getName() :"+Thread.currentThread().getName() +":"+maxValue);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Thread.currentThread().getName() :"+Thread.currentThread().getName() +":"+maxValue+":"+reminder);
            lock.notifyAll();
            maxValue=maxValue+1;
            }
        }

}

为公共锁添加一个静态对象属性,因此请锁定此对象而不是自线程。让我知道这是否无效。