线程4-线程通信

1、线程间的通信主要靠三个方法
(1)wait(),使当前线程放弃cpu、对象锁,重新排队等待对共享资源的访问
(2)notify(),唤醒等待线程中优先级最高的线程,执行共享资源
(3)notifyAll(),唤醒所有的等待线程
(4)这三个方法是object里面的方法,而非thread方法,这些方法,只有在synchronized代码块或方法中才能使用
否则会报,IlligalMonitorStateException,异常

2、线程通信例子,要注意的事项在注释里面,实现两个线程轮流打印1到100的数据

package com.thread.test;

//实现两个线程轮流打印1到100的数据,synchronized所放位置有问题的例子
class PrintNumber implements Runnable {
    int i = 0;

    @Override
    public void run() {
        synchronized (this) {// 有问题,如果这样,就会一个线程执行完while里面的代码后才出来
            notify();// 唤醒别的线程,因为当前线程已经拿到对象锁,所以可以唤醒其它线程
            while (i < 101) {

                System.out.println("线程 " + Thread.currentThread().getName()
                        + " 打印出:" + i);
                i++;
            }
            try {
                wait();// 打印出一个数字后后等待
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

// 下面锁的位置没有问题
class PrintNumberNew implements Runnable {
    int i = 0;

    @Override
    public void run() {

        while (true) {
            synchronized (this) {// 有问题,如果这样,就会一个线程执行完while里面的代码后才出来
                notify();// 唤醒别的线程,因为当前线程已经拿到对象锁,所以可以唤醒其它线程
                if (i < 101) {
                    System.out.println("线程 " + Thread.currentThread().getName()
                            + " 打印出:" + i);
                    i++;
                } else {
                    break;
                }
                try {
                    wait();// 打印出一个数字后后等待
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
    }

}

/**
 * 线程间的通信主要靠三个方法 (1)wait(),使当前线程放弃cpu、对象锁,重新排队等待对共享资源的访问
 * (2)notify(),唤醒等待线程中优先级最高的线程,执行共享资源 (3)notifyAll(),唤醒所有的等待线程
 * (4)这三个方法是object里面的方法,而非thread方法,这些方法,只有在synchronized代码块或方法中才能使用
 * 否则会报,IlligalMonitorStateException,异常
 */

public class 线程通信 {
    public static void main(String[] args) {
        PrintNumberNew pn = new PrintNumberNew();

        Thread t1 = new Thread(pn);
        Thread t2 = new Thread(pn);

        t1.setName("1");
        t2.setName("2");
        t1.start();
        t2.start();
    }
}
原文地址:https://www.cnblogs.com/fubaizhaizhuren/p/5066542.html