首页 > 编程语言 > 详细

线程通信的两种方法和lock锁

时间:2021-05-04 23:41:34      阅读:32      评论:0      收藏:0      [点我收藏+]

19.Lock显示锁

  1. 它的jdk1.5的新特性,是juc 全程(java.util.concurrent)下面的接口

  2. ReentrantLock实现了Lock是可重入锁,显示锁,释放锁

  3. 代码演示

    package com.wen.Lock;
    
    import java.util.Locale;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @Author WangEn
     * @CreateTime: 2021-05-04-16-23
     * @Emile: wen_5988@163.com
     */
    public class TestLock {
        public static void main(String[] args) {
            TestLock2 testLock21 = new TestLock2();
            new Thread(testLock21).start();
            new Thread(testLock21).start();
            new Thread(testLock21).start();
        }
    }
    
    class TestLock2 implements Runnable {
        int tickNums = 10;
        private final ReentrantLock lock = new ReentrantLock(); // 定义显示锁
    
        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock(); // 加锁
                    if (tickNums > 0) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(tickNums--);
                    } else {
                        break;
                    }
                }finally {
                    lock.unlock();  // 释放锁
                }
    
            }
        }
    }
    
    

    20.线程通信

技术分享图片
技术分享图片

21.线程通信管程法

package com.wen.Lock;

/**
 * @Author WangEn
 * @CreateTime: 2021-05-04-16-59
 * @Emile: wen_5988@163.com
 */
// 测试生产者与消费者模型-->利用缓冲区解决:管程法
public class Test管程法 {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        // 生产者
        new Producer(container).start();
        // 消费者
        new Consumer(container).start();
    }
}

// 生产者
class Producer extends Thread {
    SynContainer container;

    public Producer(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Chicken(i));
            System.out.println("生产了" + i + "只鸡");
        }
    }
}

// 消费者
class Consumer extends Thread {
    SynContainer container;

    public Consumer(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了--》" + container.pop().id + "只鸡");
        }
    }
}

// 产品
class Chicken {
    int id;// 产品编号

    public Chicken(int id) {
        this.id = id;
    }
}


// 缓冲区
class SynContainer {
    // 需要一个容器大小
    Chicken[] chickeds = new Chicken[10];
    // 容器计数器
    int count = 0;

    // 生产者放入产品
    public synchronized void push(Chicken chicken) {
        // 如果容器满了,就需要等待消费者消费
        if (chickeds.length == count) {
            // 通知消费者消费
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 容器没有满,就继续丢人产品
        chickeds[count] = chicken;
        count++;
        // 可以通知消费者消费了
        this.notifyAll();
    }


    // 消费者消费产品
    public synchronized Chicken pop() {
        // 判断能否消费
        if (count == 0) {
            // 如果没有鸡了等待生产者生产
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 可以消费
        count--;
        Chicken chicken = chickeds[count];
        // 吃完了,通知生产者生产
        this.notifyAll();
        return chicken;
    }

}

22.线程通信:标示位方法2

package com.wen.Lock;

/**
 * @Author WangEn
 * @CreateTime: 2021-05-04-17-39
 * @Emile: wen_5988@163.com
 */
// 方法2:生产者与消费者:标志位
public class Test标志位 {
    public static void main(String[] args) {
        TV tv = new TV();
        new Player(tv).start();
        new Watcher(tv).start();
    }
}

// 生产者演员
class Player extends Thread{
    TV tv;
    public Player(TV tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (i%2==0){
                this.tv.play("快乐大本营");
            }else {
                this.tv.play("抖音:记录美好生活");
            }
        }
    }
}

// 消费者  观众
class Watcher extends Thread{
    TV tv;
    public Watcher(TV tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            this.tv.watch();
        }
    }
}

// 产品  节目
class TV {
    /**
     * 演员表演  观众等待 true
     * 观众观看  演员等待 false
     */
    String voice;// 表单的节目
    boolean flag = true; // 标志位

    // 表演
    public synchronized void play(String voice){
        if (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员--》表演了"+voice);
        // 通知观众观看
        this.notifyAll();  // 唤醒
        this.voice = voice;
        this.flag = !this.flag;
    }

    // 观看
    public synchronized void watch(){
        if (flag){
            // 演员表演,观众等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观众观看了:"+voice);
        // 通知演员表演
        this.notifyAll();
        this.flag = !this.flag;
    }
}

线程通信的两种方法和lock锁

原文:https://www.cnblogs.com/WangEn/p/14729952.html

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