简体   繁体   English

Java线程同步意外输出

[英]Java Threads synchronization unexpected output

I am studying for the OCPJP exam and having a hard time understanding threads. 我正在为OCPJP考试而学习,并且很难理解线程。 In particular, I have this program out lined below. 特别是,我在下面列出了该程序。 When I run this program I get the following output and it is confusing me. 当我运行该程序时,得到以下输出,这使我感到困惑。

Inside push method...
Inside push method now sleeping...
Exit from main()
Inside push method stopped sleeping...
Exiting push method...
Pushed: true
Popped: 2008
Inside push method...
Inside push method now sleeping...
Inside push method stopped sleeping...
Exiting push method...
Pushed: true
Inside push method...
Inside push method now sleeping...
Inside push method stopped sleeping...
Exiting push method...
Pushed: true
Popped: 2008
Inside push method...
Inside push method now sleeping...
Popped: 2008

What is getting me is the last line of the output. 让我明白的是输出的最后一行。 The api says the thread does not lose ownership of any monitors/lock when sleep is called. api表示在调用睡眠时线程不会失去对任何监视器/锁的所有权。 How is it that the following: 以下内容如何:

Inside push method now sleeping...
Popped: 2008
can occur since the moment we enter the synchronized method push(), push() has the monitor/lock, why are we able execute the pop() method while the push() is sleeping? 自从我们进入同步方法push()的那一刻起就可能发生,push()具有监视/锁定功能,为什么我们可以在push()处于休眠状态时执行pop()方法? I need assistance, may someone please give an easy to understand explanation? 我需要帮助,可能有人请给出一个易于理解的解释吗?

 class StackImpl { //(1) private Object[] stackArray; private int topOfStack; public StackImpl(int capacity){ stackArray = new Object[capacity]; topOfStack = -1; } // public boolean push(Object element){ //(2a) non-synchronized public synchronized boolean push(Object element){ //(2b) synchronized if(isFull()) return false; System.out.println("Inside push method..."); ++topOfStack; try{ System.out.println("Inside push method now sleeping..."); Thread.sleep(10000); System.out.println("Inside push method stopped sleeping...");} catch(Exception e){} //(3) Sleep a little stackArray[topOfStack] = element; System.out.println("Exiting push method..."); return true; } //public Object pop(){ //(4a) non-synchronized public synchronized Object pop(){ //(4b) synchronized if(isEmpty()) return null; Object obj = stackArray[topOfStack]; stackArray[topOfStack] = null; try{Thread.sleep(1000);}catch(Exception e){} //(5) Sleep a little topOfStack--; return obj; } public boolean isEmpty(){return topOfStack < 0;} public boolean isFull(){return topOfStack >= stackArray.length - 1;} } public class Mutex{ public static void main(String[] args) throws InterruptedException { final StackImpl stack = new StackImpl(20); //(6) Shared by the threads (new Thread("Pusher"){ //(7) Thread no. 1 public void run(){ for(;;){ System.out.println("Pushed: " + stack.push(2008)); } } }).start(); // make sure Thread no.1 goes first Thread.sleep(2000); (new Thread("Popper"){ //(8) Thread no.2 public void run(){ for(;;){ System.out.println("Popped: " + stack.pop()); } } }).start(); System.out.println("Exit from main()"); } } 

The output is consistent, but it doesn't directly correspond with operations on the stack (the separate calls to println and pop / push are not atomic). 输出是一致的,但并不直接与堆栈上的操作相对应(对printlnpop / push的单独调用不是原子的)。 In Java, it is correct that you don't release the lock on the monitor in a Thread.sleep(n) (however it isn't true for Object.wait() ). 在Java中,不要在Thread.sleep(n)释放监视器上的锁是正确的(但是Object.wait()并非如此)。

To see the actual order, you can modify what is put onto the stack... 要查看实际订单,您可以修改放入堆栈的内容...

final  StackImpl stack = new StackImpl(20);                     //(6) Shared by the threads


(new Thread("Pusher"){                                          //(7) Thread no. 1

    public void run(){

    int i = 0;

        for(;;){
            System.out.println("Pushed: " + stack.push(i++));
        }
    }
}).start();

Now you should be able to see which push corresponds with which pop. 现在,您应该能够看到哪个推送对应于哪个弹出。

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

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