Java多线程之多条件condition接口及其相关类的使用举例

package testthread;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

/*

 * 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,

 * 要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

 * 

 * 使用condition接口、lock类、ReentrantLock类实现线程的通信

 * 

 */

public class TestLock {

public static void main(String[] args) {

         final AlternateDemo ad = new AlternateDemo(); //在使用Java局部内部类或者匿名内部类时,若该类调用了所在方法的局部变量,则该局部变量必须使用final关键字来修饰,否则将会出现编译错误“Cannot refer to a non-final variable * inside an inner class defined in a different method”

        new Thread(new Runnable() {

            @Override

            public void run() {

                for (int i = 0; i < 10; i++) {

                    ad.loopA();

                }

            }

        }, "A").start();

        new Thread(new Runnable() {

            @Override

            public void run() {

                for (int i = 0; i < 10; i++) {

                    ad.loopB();

                }

            }

        }, "B").start();

        new Thread(new Runnable() {

            @Override

            public void run() {

                for (int i = 0; i < 10; i++) {

                    ad.loopC();

                    System.out.println("-----------------------------------");

                }

            }

        }, "C").start();

    }

}

class AlternateDemo {

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

    private Lock lock = new ReentrantLock();

    private Condition condition1 = lock.newCondition();

    private Condition condition2 = lock.newCondition();

    private Condition condition3 = lock.newCondition();

    public void loopA() {

        lock.lock();//类比去银行办理业务,此行代码相当于先拿到一个办理业务的排队号码

        try {

            //1. 判断

            if (number != 1) {

                condition1.await();//线程等待之后,该线程中的其它代码都不会被执行,就直接退出了

            }

            //2. 打印

            System.out.println(Thread.currentThread().getName());

            //3. 唤醒

            number = 2;

            condition2.signal();//尝试去唤醒一个其它等待的满足条件的线程,每个线程都会拿到一次锁,若条件满足将会执行该线程,否则将会等待

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            lock.unlock();

        }

    }

    public void loopB() {

        lock.lock();

        try {

            //1. 判断

            if (number != 2) {

                condition2.await();//等待之后将会释放锁

            }

            //2. 打印

            System.out.println(Thread.currentThread().getName());

            //3. 唤醒

            number = 3;

            condition3.signal();

            //condition3.toString();

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            lock.unlock();

        }

    }

    public void loopC() {

        lock.lock();

        try {

            //1. 判断

            if (number != 3) {

                condition3.await();

            }

            //2. 打印

            System.out.println(Thread.currentThread().getName());

            //3. 唤醒

            number = 1;

            condition1.signal();

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            lock.unlock();

        }

    }

}

猜你喜欢

转载自zxq1007097830.iteye.com/blog/2368822