• JavaEE--线程基础(中)



    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    volatile 修饰的变量, 能够保证 “内存可见性”
    在这里插入图片描述


    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述
    上述过程的完整代码如下:

    public class Demo14 {
        //使用locker对象负责加锁,wait,notify
        private static Object locker=new Object();
        public static void main(String[] args) {
            Thread t1=new Thread(() ->{
               while(true){
                   synchronized (locker){
                       System.out.println("t1 wait开始");
                       try {
                           locker.wait();
                       } catch (InterruptedException e) {
                           e.printStackTrace();
                       }
                       System.out.println("t1 wait结束");
                   }
               }
            });
            t1.start();
    
            Thread t2=new Thread(() ->{
               while(true){
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   synchronized (locker){
                       System.out.println("t2 notify开始");
                       locker.notify();
                       System.out.println("t2 notify结束");
                   }
               }
            });
            t2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    其中,我们观察到notify的开始和结束的过程是非常快的


    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述


    下面介绍代码案例

    在这里插入图片描述

    在这里插入图片描述****
    饿汉模式
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    懒汉模式
    类加载的时候不创建实例. 第一次使用的时候才创建实例.
    因为只有使用getInstance的时候,才会new出来一个对象;而在饿汉模式下,instance被当做一个类的属性,在类的加载的时候就被创建了。

    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    在这里插入图片描述


    在这里插入图片描述
    上述过程的完整代码如下:

    import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
    
    import java.util.concurrent.BlockingDeque;
    import java.util.concurrent.LinkedBlockingDeque;
    
    //生产者消费者模型
    public class Demo18 {
        public static void main(String[] args) {
            //建一个阻塞队列,作为交易场所
            BlockingDeque<Integer> queue=new LinkedBlockingDeque<>();
    
            //一个线程负责生产
            Thread t1=new Thread(() ->{
                int count=0;
               while(true){
                   try {
                       queue.put(count);
                       System.out.println("生产的元素为:"+count);
                       count++;
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            });
    
            //一个线程负责消耗
            Thread t2=new Thread(() ->{
                while(true){
                    try {
                        Integer n=queue.take();
                        System.out.println("消耗的元素为:"+n);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t1.start();
            t2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    阻塞队列的模拟实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    下面首先实现一般的队列
    在这里插入图片描述
    上述过程的代码如下:

    class MyBlockingQueue{
        //使用循环队列来表示这个阻塞队列
        private String[] items=new String[1000];
        //队列的头部
        int head=0;
        //tail:队列的尾部的下一个元素. 总的来说, 队列中有效元素的范围 [head, tail)
        // 当 head 和 tail 相等(重合), 相当于空的队列.
        int tail=0;
        //size表示队列当前的元素个数
        int size=0;
    
        public void put(String elem){
            if(size>=items.length){//队列满
                return;
            }
            items[tail]=elem;
            tail++;
            if(tail>= items.length){
                tail=0;
            }
            size++;
        }
        public String take(){
            if(size==0){
                return null;
            }
            String elem=items[head];
            head++;
            if(head>= items.length){
                head=0;
            }
            size--;
            return elem;
        }
    }
    public class Demo19 {
        public static void main(String[] args) {
        MyBlockingQueue queue=new MyBlockingQueue();
        queue.put("aaa");
        queue.put("bbb");
        queue.put("ccc");
        queue.put("ddd");
    
        String elem= queue.take();
        System.out.println("elem="+elem);
        elem= queue.take();
        System.out.println("elem="+elem);
        elem= queue.take();
        System.out.println("elem="+elem);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    在这里插入图片描述

    考虑线程安全在这里插入图片描述


    在这里插入图片描述

    实现阻塞
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    上述实现过程的最终代码如下:

    class MyBlockingQueue{
        //使用循环队列来表示这个阻塞队列
        private String[] items=new String[10];
        //队列的头部
        volatile int head=0;
        //tail:队列的尾部的下一个元素. 总的来说, 队列中有效元素的范围 [head, tail)
        // 当 head 和 tail 相等(重合), 相当于空的队列.
        volatile int tail=0;
        //size表示队列当前的元素个数
        volatile int size=0;
    
        public void put(String elem) throws InterruptedException {
            synchronized (this){
                while(size>=items.length){//队列满
                    //return;
                    this.wait();
                }
                items[tail]=elem;
                tail++;
                if(tail>= items.length){
                    tail=0;
                }
                size++;
                this.notify();
            }
        }
        public String take() throws InterruptedException {
            synchronized (this){
                while(size==0){
                   // return null;
                    this.wait();
                }
                String elem=items[head];
                head++;
                if(head>= items.length){
                    head=0;
                }
                size--;
                this.notify();
                return elem;
            }
        }
    }
    public class Demo19 {
        public static void main(String[] args) {
    /*    MyBlockingQueue queue=new MyBlockingQueue();
        queue.put("aaa");
        queue.put("bbb");
        queue.put("ccc");
        queue.put("ddd");
    
        String elem= queue.take();
        System.out.println("elem="+elem);
        elem= queue.take();
        System.out.println("elem="+elem);
        elem= queue.take();
        System.out.println("elem="+elem);*/
            //创建两个线程,表示生产者和消费者
            MyBlockingQueue queue=new MyBlockingQueue();
            Thread t1=new Thread(() ->{
                int count=0;
               while (true){
                   try {
                       queue.put(count + "");
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println("生产"+count);
                   count++;
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            });
            Thread t2=new Thread(() ->{
                while (true){
                    String elem= null;
                    try {
                        elem = queue.take();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("消耗"+elem);
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t1.start();
            t2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

  • 相关阅读:
    柯桥增值税留抵如何退税?
    验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
    MFC Windows 程序设计[230]之驱动盘列表拾取器(附源码)
    1997-2017年各省能源投入数据(万吨标准煤)
    leetcode电话号码的字母组合
    软件测试 - Linux的远程连接
    DC-DC模块升压电源直流隔离低压升高压正负输出变换器
    Mac文件搜索工具HoudahSpot 6.4.1中文版
    基于Java+SpringBoot+Mybaties+Vue 在线问卷调查系统设计与实现
    【Unity】实现轮盘抽奖
  • 原文地址:https://blog.csdn.net/qq_43570634/article/details/133238164