简体   繁体   English

在程序中出现不一致/错误的输出多线程java

[英]getting inconsistent/wrong output in the program Multi -Threading java

/*
This should always produce 0 as output since all three methods increment(), decrement(), value()  are thread safe(synchronized).  but it is returning 1
*/

class Counter implements Runnable {
    private int c = 0;

    public  synchronized void increment() {
        c++;
    }
    public synchronized void decrement() {
        c--;
    }
    public synchronized int value() {
        return c;
    }
    public void run() {
        try {
            this.increment();
            Thread.sleep(1000);
            this.decrement();
            Thread.sleep(1000);
            this.increment();
            Thread.sleep(1000);
            this.decrement();
            Thread.sleep(1000);
        }
        catch (InterruptedException e){
            return;
        }
    }
    public static void main(String args[]) throws InterruptedException {
       Counter c =  new Counter();
       new Thread(c).start();
       new Thread(c).start();
       System.out.println(c.value());
    }

}

like everyone else said you need to make sure that the treads have finished executing, to do that you need to call join . 就像其他所有人所说的那样,您需要确保各个步骤已完成执行,然后需要调用join for example 例如

public static void main(String args[]) throws InterruptedException {
   Counter c =  new Counter();
   Thread t1 = new Thread(c).start();
   Thread t2 = new Thread(c).start();
   t1.join();
   t2.join();
   System.out.println(c.value());
}

that should run correctly 应该可以正常运行

There's nothing to control when the main thread is calling value() . 当主线程调用value()时,没有什么可以控制的。 It will run as soon as it can acquire a lock on c , even though the other threads are still running. 只要其他线程仍在运行,它将在获取c的锁定后立即运行。

If you want to wait until the threads are done, call join() on them. 如果要等待线程完成,请在它们上调用join()

您正在线程完成执行之前读取该值,因此该值可能与零有很大不同。

You're not waiting for the threads to complete running, so the result is that the value of c is printed at whatever it is at that second. 您不是在等待线程完成运行,因此结果是c的值以该秒为单位打印。 I bet if you tried it 1000 times, there would be times when it wasn't 1. 我敢打赌,如果您尝试过1000次,那么有时可能不是1。

IBM has a fair tutorial on the situation you're encountering: http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzahw/rzahwex3rx.htm IBM针对您遇到的情况提供了一个公平的教程: http : //publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzahw/rzahwex3rx.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM