Java并发编程(六):Condition控制线程通信

Condition控制线程通信

Condition可以用来控制线程间的通信,与wait、notify和notifyAll方法对应的分别是await、signal和sinalAll

上篇文章中的生产者消费者采用的是 synchronized和对象的waitnotifyAll方法,可以采用Lock锁结合condition来代替,具体代码如下:

依然是修改Clerk类

class Clerk{
    private int product = 0;

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    
    //进货方法
    public  void get()
    {
        lock.lock();
        try {
            while (product>=10){

                System.out.println("产品已满!无法添加");
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+":"
                    + ++product);
            condition.signalAll();

        }
        finally {
            lock.unlock();
        }
    }

    //卖货方法
    public  void sale()
    {
        lock.lock();

        try {
            while (product<=0)
            {
                System.out.println("缺货!");
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+":"+
                    --product);
            condition.signalAll();
        }
        finally {
            lock.unlock();
        }
    }
}

代码逻辑:

  • 首先用Lock对象代替synchronized的作用
  • 采用condition对象的awaitsignalAll方法让线程等待和唤醒

实际执行结果:

可以达到同样的效果

线程按序交替案例

要求:开启三个线程A、B、C,每个线程分别负责打印A、B、C,要求按序打印20次

即 ABCABCABC…

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
    public static void main(String[] args)
    {
        AlternateDemo alternateDemo = new AlternateDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=1;i<=20;i++)
                {
                    alternateDemo.loopA(i);
                }
            }
        },"A").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=1;i<=20;i++)
                {
                    alternateDemo.loopB(i);
                }
            }
        },"B").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=1;i<=20;i++)
                {
                    alternateDemo.loopC(i);
                    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();

    /**
     *
     * @param totalLoop
     */
    public void loopA(int totalLoop){
        lock.lock();
        try {
            //1.判断当前标志位是否为1
            if(number != 1)
            {
                condition1.await();
            }
                System.out.println(Thread.currentThread().getName()+"\t" +
                        "\t"+ totalLoop);

            //2.A打印完毕,唤醒其他线程
            number = 2;
            condition2.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void loopB(int totalLoop){
        lock.lock();
        try {
            //1.判断当前标志位是否为2
            if(number != 2)
            {
                condition2.await();
            }

                System.out.println(Thread.currentThread().getName()+"\t" +
                        "\t"+ totalLoop);

            //2.B打印完毕,唤醒其他线程
            number = 3;
            condition3.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void loopC(int totalLoop){
        lock.lock();
        try {
            //1.判断当前标志位是否为3
            if(number != 3)
            {
                condition3.await();
            }

                System.out.println(Thread.currentThread().getName()+"\t" +
                       "\t"+ totalLoop);

            //2.C打印完毕,唤醒其他线程
            number = 1;
            condition1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
原创文章 40 获赞 16 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43925277/article/details/105162045