首页 > 编程语言 > 详细

多线程编写模板套路(lock版)

时间:2021-02-27 00:33:04      阅读:39      评论:0      收藏:0      [点我收藏+]

1) 在高内聚低耦合的前提下,线程操作资源类

资源类

class Ticket{
    private int num = 30;

    public void sale(){
        System.out.println("sale");
    }
}

主进程

    public static void main(String[] args) {
        //创建资源类
        Ticket ticket = new Ticket();

        //线程操作资源类
        new Thread(()->{
            ticket.sale();
        },"A").start();
    }

 

2) 判断/干活/通知

资源类

class ShareDate{
    private int numble = 0;
    private Lock lock = new ReentrantLock();
    private Condition[] condition = {
            lock.newCondition(),
            lock.newCondition(),
            lock.newCondition()
    };

    public void printByNum(int num){

        lock.lock();
        try{
            //判断
            if(numble != num) {
                condition[num].await();
            }
            //干活
            for (int i = 0; i < 2 * (num+1); i++){
                System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
            }
            //通知
            numble = ++numble % 3;
            condition[numble].signal();

        }catch(Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
}

主进程

    public static void main(String[] args) {
        //线程控制资源类
        ShareDate shareDate = new ShareDate();
        new Thread(()->{
            for(int i = 0; i < 4; i++){
                shareDate.printByNum(0);
            }
        },"A").start();

        new Thread(()->{
            for(int i = 0; i < 4; i++){
                shareDate.printByNum(1);
            }
        },"B").start();

        new Thread(()->{
            for(int i = 0; i < 4; i++){
                shareDate.printByNum(2);
            }
        },"C").start();
    }

  在多线程世界中,如果使用if作为判断语句,则会出现预料之外的结果:

    资源类

class NumberDemo{
    private int num = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    public void incr(){
        lock.lock();
        try{
            //判断
            if(num != 0){
                condition1.await();
            }
            //干活
            num++;
            System.out.println(Thread.currentThread().getName() + "\t:\t" + num);
            //通知
            condition2.signal();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }

    public void desc(){
        lock.lock();
        try{
            if(num != 1){
                condition2.await();
            }
            num--;
            System.out.println(Thread.currentThread().getName() + "\t:\t" + num);
            condition1.signal();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
}

  主进程

    public static void main(String[] args) {
        NumberDemo number = new NumberDemo();
        new Thread(()->{
            for (int i = 0; i < 10; i++){
                number.incr();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++){
                number.incr();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++){
                number.desc();
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++){
                number.desc();
            }
        },"D").start();
    }

  结果:

    技术分享图片

 

    出现了意料之外的结果:-1

    解决方法:不使用if来判断语句,而是使用while来代替

3) 使用while防止虚假唤醒

class ShareDate{
    private int numble = 0;
    private Lock lock = new ReentrantLock();
    private Condition[] condition = {
            lock.newCondition(),
            lock.newCondition(),
            lock.newCondition()
    };

    public void printByNum(int num){

        lock.lock();
        try{
            //判断
            while(numble != num) {
                condition[num].await();
            }
            //干活
            for (int i = 0; i < 2 * (num+1); i++){
                System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
            }
            //通知
            numble = ++numble % 3;
            condition[numble].signal();

        }catch(Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
}

 

多线程编写模板套路(lock版)

原文:https://www.cnblogs.com/pikachu511/p/14454497.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!