同步并通知执行和范围的顺序

时间:2013-12-11 03:43:10

标签: java multithreading synchronization

1)一旦在该线程同步代码块中调用notify,或者退出同步代码块,线程是否放弃它的锁定?

例如,似乎没有指定线程优先级,我的Process类将从上到下执行。首先调用Produce,然后调用stuff,然后wait();消耗将运行,然后它命中notify(),这将打印“完成”或首先会有5秒的延迟,然后“完成”将被打印?

2)另外,如果我有第三个同步的方法/线程,它不等待或通知并且只是运行,我可以预测我的操作先验执行的顺序吗?

3)最后,notify()如何知道'唤醒'的线程?比如,假设我有多个进程,每个进程同时执行2个线程,每个进程A,B和C都会激活notify()。每个进程的每个notify()都是本地的吗?换句话说,如果进程A调用notify(),是否可以唤醒进程B中的等待线程?到目前为止,我已经看到了synchronized this(this),这让我觉得它引用了一个特定的对象类,这反过来让我觉得在synchronized块中调用的所有notify()都被同步中的任何一个绑定(这是指,所以没有交叉。

public class Process {

public void produce( ) {
  synchronized(this) {
   // do stuff
    wait( );
     System.out.println("Done");
    }
}


public void consume( ) {
    synchronized(this) {
    // stuff
    notify(); 
    Thread.sleep(5000);
    }
}
}

2 个答案:

答案 0 :(得分:3)

你可以写一个简单的程序来测试这个

public static void main(String[] args) throws Exception {
    final Process e = new Process();        
    Thread t = new Thread(new Runnable() {          
        @Override
        public void run() {
            try {
                Thread.sleep(10);
                e.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    t.start();
    e.produce();
}

该程序等待5000毫秒并打印

Done

关于你的问题

  

1)一旦调用notify,线程是否放弃它的锁定   在那个线程内同步代码块,或者一旦同步   退出代码块?

notify()个州的javadoc

  

如果有任何线程在等待这个对象,选择其中一个   被唤醒选择是任意的,由酌情决定   实现。**强文线程通过调用等待对象的监视器   其中一种等待方法。

     

唤醒的线程将无法继续直到当前   线程放弃对此对象的锁定

所以,不,在调用notify()时,线程不会放弃对锁的控制。当代码退出synchronized块时,就会发生这种情况。

  

2)另外,如果我有第三个同步方法/线程,那不会   等待或通知,只是运行,我可以预测我的顺序   操作先验执行?

你可以估计,但你不能确定。执行由Thread调度程序决定。

  

3)最后,notify()如何知道'唤醒'的线程?

电话不知道。 Thread调度程序知道并选择。你无法控制它。

wait()notify()

的javadoc
  

此方法只应由作为其所有者的线程调用   这个对象的监视器。

  

IllegalMonitorStateException - 如果当前线程不是所有者   该对象的监视器。

因此,当您在同一个对象上的synchronized块内时,您只能在对象上调用它们。

在您的代码示例中,调用

wait();

隐含地做

this.wait();

答案 1 :(得分:2)

  

一旦在该线程同步代码块中调用notify,或者退出同步代码块,线程是否放弃它的锁定?

当'synchronized'块退出时。 notify()本身并不影响锁定。

  

首先会有5秒的延迟,然后会打印“完成”吗?

  

另外,如果我有第三个同步方法/线程,它不等待或通知并且只是运行,我可以预测我的操作先验执行的顺序吗?

您无法使用线程预测任何内容。如果您想要特定的执行订单,则不会使用它们。

  

最后,notify()如何知道'唤醒'的线程?

没有。它'唤醒正在等待此对象监视器的单个线程。如果任何线程正在等待此对象,则选择其中一个线程被唤醒。选择是任意的,由实施决定。

  

就像我们说的那样,我有多个进程同时执行2个线程,每个进程A,B和C都会激活notify()。每个进程的每个notify()都是本地的吗?

notify()与您的课程无关。它会通知对象并唤醒线程。

  

换句话说,如果进程A调用notify(),是否可以唤醒进程B中的等待线程?

  

到目前为止,我已经看过synchronized called(this),这让我认为它指的是一个特定的对象类

没有。它指的是特定的对象。

  

反过来让我认为同步块中调用的所有notify()都被synchronized(this)所引用的内容绑定,因此不存在交叉。

不要这么想。你过度思考了这一点。 synchronized(x)在对象x上进行同步,x.notify()通知它。周期。