线程的交互

来源:互联网 发布:果核源码 编辑:程序博客网 时间:2024/06/05 14:55
      一个线程一般只有一把锁,那么多线程之间势必会发生联系或者程序中的一把锁被一个线程获得之后,其它线程是否真的就处于阻塞状态不在执行了呢?答案当然是否定的,那么这一把锁该如何在多线程之间来回交替使用呢?下面就是线程之间的交互了。

      所谓线程的交互就是程序里唯一的synchronized是如何在多线程之间进行传递的。

在交互中主要用到的方法:

Public void wait() :导致当前的正在运行的线程等待,直到其他线程调用此对象的 notify() 方法或notifyAll() 方法。

Public void wait(long timeout) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
public void wait(long timeout, int nanos) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。

void notify() :唤醒在此对象监视器上等待的单个线程。

void notifyAll():唤醒在此对象监视器上等待的所有线程。

注意:

1.线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。

2.Wait(),notify(),notifyAll()在同步环境变量中调用。

3.XX.wait(),XX.notify(),XX.notifyAll()中的XX指的是监视器而不是对象。Wait停止进行的是其所者的主线程。

下面是一段两线程交互的代码:

   public class ThreadA {
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        //启动计算线程
        b.start();
        //线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
        synchronized (b) {
            try {
                System.out.println("等待对象b完成计算。。。");
                //当前线程A等待
                b.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("b对象计算的总和是:" + b.total);
        }
    }
}

 

/**
* 计算1+2+3 ... +100的和
*/
public class ThreadB extends Thread {
    int total;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 101; i++) {
                total += i;
            }
            //(完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒
            notify();
        }
    }
}

注意:当在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。然而调用notify()时,并不意味着这时线程会放弃其锁。如果线程仍然在完成同步代码,则线程在移出之前不会放弃锁。因此,只要调用notify()并不意味着这时该锁变得可用。