Day16-Java进阶-线程通信线程生命周期线程池单例设计模式

1. 线程通信

1.1 线程通信介绍

1.2 两条线程通信

package com.itheima.correspondence;

public class CorrespondenceDemo1 {
    /*
        两条线程通信
     */
    public static void main(String[] args) {
        Printer1 p = new Printer1();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Printer1.class) {
                    while (true) {
                        try {
                            p.print1();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Printer1.class) {
                    while (true) {
                        try {
                            p.print2();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

}

class Printer1 {

    int flag = 1;

    public void print1() throws InterruptedException {

        if (flag!=1){
            // 等待线程2
            Printer1.class.wait();
        }

        System.out.print("传");
        System.out.print("智");
        System.out.print("教");
        System.out.print("育");
        System.out.println();

        flag = 2;
        // 唤醒线程2
        Printer1.class.notify();
    }

    public void print2() throws InterruptedException {

        if (flag != 2) {
            // 等待线程1
            Printer1.class.wait();
        }

        System.out.print("黑");
        System.out.print("马");
        System.out.print("程");
        System.out.print("序");
        System.out.print("员");
        System.out.println();

        flag = 1;
        // 唤醒线程1
        Printer1.class.notify();
    }
}

1.3 三条线程通信

对于三条线程通信, 使用notifyAll(), 唤醒所有进程以避免死锁

package com.itheima.correspondence;

public class CorrespondenceDemo2 {
    /*
        三条线程通信

        问题: sleep方法和wait方法的区别?
        回答:
                sleep方法是线程休眠, 时间到了自动醒来, sleep方法在休眠的时候, 不会释放锁.
                wait方法是线程等待, 需要由其它线程进行notify唤醒, wait方法在等待期间, 会释放锁.
     */
    public static void  main(String[] args) {

        Printer2 p = new Printer2();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Printer2.class) {
                    while (true) {
                        try {
                            p.print1();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Printer2.class) {
                    while (true) {
                        try {
                            p.print2();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Printer2.class) {
                    while (true) {
                        try {
                            p.print3();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

}
}


class Printer2 {

    int flag = 1;

    public void print1() throws InterruptedException {

        if (flag != 1) {
            Printer2.class.wait();
        }
        System.out.print("传");
        System.out.print("智");
        System.out.print("教");
        System.out.print("育");
        System.out.println();

        flag = 2;
        Printer2.class.notifyAll();

    }

    public void print2() throws InterruptedException {

        if (flag != 2) {
            Printer2.class.wait();
        }
        System.out.print("黑");
        System.out.print("马");
        System.out.print("程");
        System.out.print("序");
        System.out.print("员");
        System.out.println();

        flag = 3;
        Printer2.class.notifyAll();
    }

    public void print3() throws InterruptedException {

        if (flag != 3) {
            Printer2.class.wait();
        }
        System.out.print("传");
        System.out.print("智");
        System.out.print("大");
        System.out.print("学");
        System.out.println();

        flag = 1;
        Printer2.class.notifyAll();
    }
}

1.4 三条线程通信的优化

package com.itheima.correspondence;

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

public class CorrespondenceDemo3 {
    /*
        三条线程通信 - 优化:
                将同步信号synchronized换成ReentrantLock
     */
    public static void main(String[] args) {

        Printer3 p = new Printer3();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        p.print1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        p.print2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        p.print3();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }
}

class Printer3 {

    ReentrantLock lock = new ReentrantLock();

    Condition c1 = lock.newCondition();
    Condition c2 = lock.newCondition();
    Condition c3 = lock.newCondition();

    int flag = 1;

    public void print1() throws InterruptedException {

        // 上锁
        lock.lock();

        if (flag != 1){
            // 线程1等待, c1绑定线程1
            c1.await();
        }

        System.out.print("传");
        System.out.print("智");
        System.out.print("教");
        System.out.print("育");
        System.out.println();

        flag = 2;
        c2.signal();

        // 解锁
        lock.unlock();

    }

    public void print2() throws InterruptedException {

        lock.lock();

        if (flag != 2){
            // 线程2等待, c2绑定线程2
            c2.await();
        }

        System.out.print("黑");
        System.out.print("马");
        System.out.print("程");
        System.out.print("序");
        System.out.print("员");
        System.out.println();

        flag = 3;
        c3.signal();

        lock.unlock();
    }

    public void print3() throws InterruptedException {

        lock.lock();

        if (flag != 3){
            // 线程3等待, c3绑定线程3
            c3.await();
        }

        System.out.print("传");
        System.out.print("智");
        System.out.print("大");
        System.out.print("学");
        System.out.println();

        flag = 1;
        c1.signal();

        lock.unlock();
    }
}

1.5 案例-生产消费模式

package com.itheima.producer_consumer;

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

public class WareHouse {
    /**
     * 缓冲区域
     */
    public static boolean mark = false;
    public static ReentrantLock lock = new ReentrantLock();
    public static Condition producer = lock.newCondition();
    public static Condition consumer = lock.newCondition();


}
package com.itheima.producer_consumer;

public class Producer implements Runnable {
    /*
        生产者
     */

    @Override
    public void run() {
        while (true) {
            WareHouse.lock.lock();
            if (WareHouse.mark){
                try {
                    WareHouse.producer.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("生产者线程生产了包子...");
            WareHouse.mark = true;
            WareHouse.consumer.signal();
            WareHouse.lock.unlock();
        }
    }
}
package com.itheima.producer_consumer;

public class Consumer implements Runnable{
    /*
        消费者
     */

    @Override
    public void run() {
        while (true) {
            WareHouse.lock.lock();
            if (!WareHouse.mark){
                try {
                    WareHouse.consumer.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("消费者吃了包子...");
            WareHouse.mark = false;
            WareHouse.producer.signal();
            WareHouse.lock.unlock();
        }
    }
}
package com.itheima.producer_consumer;

public class Test {
    /*
        测试类
     */
    public static void main(String[] args) {
        new Thread(new Producer()).start();
        new Thread(new Consumer()).start();
    }
}

2. 线程生命周期

注: 面试时最好能画出来

3. 线程池

~见Day15最后一节

4. 单例设计

4.1 单例设计-饿汉式

package com.itheima.single_design;

public class SingleDesignDemo1 {
    /*
        单例设计模式 - 饿汉式(推荐使用, 简单不复杂)

        -----------------------------------------------------------------

        class Single1 {
            private Single1() {
            }

            public static final Single1 s = new Single1();
        }

        -----------------------------------------------------------------
     */
    public static void main(String[] args) {
        
        Single1 s = Single1.getInstance();

        System.out.println(s);
    }
}

class Single1 {
    private Single1() {
    }

    private static Single1 s = new Single1();

    public static Single1 getInstance() {
        return s;
    }
}

4.2 单例-懒汉式(延迟加载模式)

package com.itheima.single_design;

public class SingleDesignDemo2 {
    /*
        单例设计模式 - 懒汉式 (延迟加载模式) --- 面试时可能会问到

        --------------------------------------------------

            class Single2 {

                private Single2() {
                }

                private static Single2 s;

                public static Single2 getInstance() {
                    if (s == null) {
                        s = new Single2();
                    }
                    return s;
                }

            }

            弊端: 在多线程并发操作的时候, 有可能创建出多个对象.

        --------------------------------------------------

            class Single2 {

                private Single2() {
                }

                private static Single2 s;

                public static Single2 getInstance() {
                    synchronized (Single2.class) {
                        if (s == null) {
                            s = new Single2();
                        }
                    }
                    return s;
                }

            }

            弊端: 效率非常低

        --------------------------------------------------
     */
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Single2 s = Single2.getInstance();
                    System.out.println(s);
                }
            }).start();
        }
    }
}

class Single2 {

    private Single2() {
    }

    private static Single2 s;

    public static Single2 getInstance() {
        // 线程2
        // 线程1
        // 此处第一个 if (s == null) 用于提高效率, 避免线程多次重复阻塞, 影响效率
        if (s == null) {
            synchronized (Single2.class) {
                // 第二个 if (s == null) 避免产生不同的线程
                if (s == null) {
                    s = new Single2();
                }
            }
        }

        return s;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/570875.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习运用-民宿价格

项目简介 随着旅游业的蓬勃发展&#xff0c;民宿市场迎来了前所未有的增长机遇。正好最近在参加拓尔思数据挖掘公益实习活动&#xff0c;我的项目将应用机器学习技术开发一个价格预测模型。可以达到更好地理解和预测民宿价格的目的&#xff0c;该模型综合考虑了从容纳人数、便…

【Java】文件操作(一)

文章目录 ✍一、文件的基本认识1.文件是什么&#xff1f;2.文本文件和二进制文件3.文件权限4.相对路径和绝对路径1.1绝对路径1.2相对路径 ✍二、文件的基本操作1.FIle的属性2.File的构造方法3.File类的方法3.1File类的获取操作3.2File类的判断操作3.3文件创建和删除3.4其他的常…

this指向

调用方式示例 函数中this的指向通过new调用new method()新对象直接调用method()全局对象通过对象调用obj.method()前面的对象call、apply、bindmethod.call(ctx)第一个参数 我们说的this指向是一个函数里边的this指向&#xff0c;如果这个this不在函数里边&#xff0c;那th…

C. Inhabitant of the Deep Sea

本题链接&#xff1a;Problem - C - Codeforces 题目&#xff1a; 样例&#xff1a; 输入 6 4 5 1 2 4 3 4 6 1 2 4 3 5 20 2 7 1 8 2 2 2 3 2 2 15 1 5 2 7 5 2输出 2 3 5 0 2 2 思路&#xff1a; 数学模拟。 根据题意&#xff0c;一前一后的攻击&#xff0c;攻击k次后&…

PotPlayer详细安装教程

安装步骤 进入官网&#xff1a; https://potplayer.tv/ 根据自己电脑的windows系统选择对应的版本安装 选择合适的字体 下载完成 优化设置 刚下好的potplayer仅限于能用&#xff0c;所有设置均为默认状态&#xff0c;我们需要进行优化 首先打开potplayer 右击选择选项 在…

三、CPU基础-缓存

计算机中缓存一般分为两个部分 1.内存 2.CPU Cache 一、CPU Cache分级 CPU Cache 通常分为大小不等的三级缓存&#xff0c;分别是 L1 Cache、L2 Cache 和 L3 Cache。 L1 Cache 和 L2 Cache 都是每个 CPU 核心独有的&#xff08;通常会分为「数据缓存」和「指令缓存」&#…

Git--原理与使用

目录 一、课程目标二、初始Git三、安装Git3.1 Linux-centos 四、Git的基本操作4.1 创建Git本地仓库 五、配置Git六、认识工作区、暂存区、版本库七、添加文件八、查看.git九、修改文件十、版本回退十一、撤销修改11.1 情况一&#xff1a;对于工作区的代码&#xff0c;还有add11…

海康NVR接入视频监控平台部分视频浏览失败,显示503错误的解决办法

目录 一、问题概述 二、问题排查 &#xff08;一&#xff09;排查思路介绍 &#xff08;二&#xff09;平台排查 1、确定排查的思路 2、信令控制模块的排查 3、媒体转发模块的排查 &#xff08;三&#xff09;客户设备排查 1.观察正常视频的设置 2. 调查问题原因 三…

B端设计实战:基于角色属性的权限设计

编辑导读:“权限控制”是中后台的基础能力,用于管控操作人员在平台内可做的事项内容。即通过权限控制,可以决定哪些人在平台内可以做哪些事。本文作者围绕角色&属性的权限设计展开分析,希望对你有帮助。 Hello,我是一名交互设计师。 随着3月暖春的即将到来,苏州的疫…

足球场体育馆三维可视化:颠覆传统观赛体验,开启视觉新纪元

在数字化浪潮席卷全球的今天&#xff0c;三维可视化技术正以其独特的魅力引领着体育场馆建设的革新潮流。这一技术的出现&#xff0c;不仅为观众带来了前所未有的视觉享受&#xff0c;更在体育产业的发展中&#xff0c;开启了一扇通往未来的大门。 足球场体育馆三维可视化&…

YOLOV1学习笔记

1. 前置知识简介 1.1 方向梯度直方图&#xff08;HOG, Histogram of Oriented Gradient&#xff09; 在计算机视觉以及数字图像处理中方向梯度直方图是一种能对物体进行检测的基于形状边缘特征的描述算子&#xff08;用于量化图像局部特征的算法工具&#xff0c;它将图像中的…

string 类以及模拟实现

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

Flutter 中优雅切换应用主题的组件

Flutter 中优雅切换应用主题的组件 视频 https://youtu.be/L–XLpc452I https://www.bilibili.com/video/BV1wD421n75p/ 前言 原文 https://ducafecat.com/blog/flutter-app-theme-switch Adaptive Theme 这个组件通过包裹 MaterialApp 的方式整体管理 theme 主题&#xff0…

Java冲突

本身 父类 接口(多) 如果出现同样名字的方法,就会出现冲突 * 情况描述1: * 当一个类,继承了父类,实现了某接口,父类中的成员方法和接口中的方法重名 * 解决方法: * 子类就近选择父类成员方法 亲爹优先原则 * *使用格式: * 父类:super.方法名 * 父接口:父接口名.super.方…

QT——其他方式实现HelloWrold

QT——其他方式实现HelloWrold 使用输入框实现使用代码实现 通过按钮实现信号槽代码方式实现 我们之前对QT实现HelloWorld有了一些基本的了解&#xff0c;用了一些简单的方法实现了HelloWorld&#xff0c;如果对QT还不怎么了解的&#xff0c;可以点击这里&#xff1a; https://…

算法提高 第一期 KMP扩展算法

1## 具体思路&#xff1a; 和KMP算法的是想类似&#xff0c;充分利用已经比较字符性质来减少冗余的字符比较次数。KMP的思想是充分的利用模式串中所有前缀字串&#xff08;以模式串为开头的字串&#xff09;的真前缀和真后缀&#xff08;指子串的开始字符与子串的最后字符相等的…

【C 数据结构】二叉树

文章目录 【 1. 基本原理 】1.1 二叉树的性质1.2 满二叉树1.3 完全二叉树 【 2. 二叉树的顺序存储结构 】2.1 完全二叉树的顺序存储2.2 普通二叉树的顺序存储2.3 完全二叉树的还原 【 3. 二叉树的链式存储结构 】【 4. 二叉树的先序遍历 】4.1 递归实现4.2 非递归实现 【 5. 二…

MongoDB磁盘空间占满,导致数据库被锁定,如何清理数据和磁盘空间

一、问题 1、我在实际项目中&#xff0c;遇到一个问题&#xff0c;随着数据每天的不断增加&#xff0c;导致mongodb的磁盘空间站满了&#xff0c;数据库被锁了&#xff0c;无法使用。 2、故障表现 部署的应用程序突然无法将数据写入数据库&#xff0c;但是可以正常读取数据。…

栈和队列详解

目录 栈栈的概念及结构栈的实现数组栈的实现数组栈功能的实现栈的初始化void STInit(ST* pst)初始化情况一初始化情况二 代码栈的插入void STPush(ST* pst, STDataType x)代码 栈的删除void STPop(ST* pst)代码 栈获取数据STDataType STTop(ST* pst)代码 判断栈是否为空bool ST…

裸金属服务器是什么

自推出裸金属服务器以来&#xff0c;它一直断断续续地出现在我们面前。最近&#xff0c;关于裸金属服务器、什么是裸金属服务器、裸金属服务器可以做什么、数据托架共享的讨论越来越多&#xff1a; 裸金属服务器&#xff08;bare metal server&#xff0c;BMS&#xff09;的官…