Java多线程之间的线程通信

  • 【线程通信示例一: 两个线程交替打印1-100】
public class CommunicationTest {

    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }

}

/**
 * 线程通信涉及到的方法
 * wait() 一旦执行此方法  当前线程进入阻塞状态、并释放同步监视器
 * notify() 一旦执行此方法 就会唤醒wait的一个线程、如果有多个线程被wait、会唤醒优先级高的
 * notifyAll() 唤醒所有wait的线程
 *
 * 说明
 * wait() notify() notifyAll() 三个方法必须使用在同步方法或同步代码块中
 *
 *
 */

class Number implements Runnable {

    private int num = 1;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {

                //唤醒一个线程
                notify();

                if (num <= 100) {

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":" + num);
                    num++;

                    //使得调用wait方法的线程进入阻塞状态、会释放锁
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                } else {
                    break;
                }
            }
        }
    }
}
  • 【线程通信示例二: 开启3个线程、线程ID 分别是 A B C 、每个线程都将自己的ID打印10遍、结果必须按顺序显示、如: ABCABC…】
public class TestABCPrint {

    public static void main(String[] args) {
        AlternateDemo ad = new AlternateDemo();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 10; i++) {
                    ad.loopA(i);
                }
            }
        },"A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 10; i++) {
                    ad.loopB(i);
                }
            }
        },"B").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 10; i++) {
                    ad.loopC(i);
                    System.out.println("-------------------------------------");
                }
            }
        },"C").start();
    }
}

class AlternateDemo {

    //表示当前正在执行线程的标记
    private int number = 1;

    private Lock lock = new ReentrantLock();

    private Condition con1 = lock.newCondition();
    private Condition con2 = lock.newCondition();
    private Condition con3 = lock.newCondition();

    /**
     *
     * @param totalLoop 循环第几轮
     */
    public void loopA(int totalLoop) {
        //上锁
        lock.lock();

        try {
            //1. 判断
            if (number != 1) {
                con1.await();
            }

            //2. 打印
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i + " " + totalLoop);
            }

            //3 唤醒
            number = 2;
            con2.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }
    }

    public void loopB(int totalLoop) {
        //上锁
        lock.lock();

        try {
            //1. 判断
            if (number != 2) {
                con2.await();
            }

            //2. 打印
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i + " " + totalLoop);
            }

            //3 唤醒
            number = 3;
            con3.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }
    }

    public void loopC(int totalLoop) {
        //上锁
        lock.lock();

        try {
            //1. 判断
            if (number != 3) {
                con3.await();
            }

            //2. 打印
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i + " " + totalLoop);
            }

            //3 唤醒
            number = 1;
            con1.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }
    }
}

你可能感兴趣的:(Java)