首页 > 其他分享 >2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程

时间:2023-07-05 22:31:55浏览次数:42  
标签:String Thread void phone 线程 2023 public 礼让

线程复习

1. 线程的休眠

需求:编写一个抽取学员回答问题的程序,要求倒数三秒后输出被抽中的学员姓名

分析:

1. 创建String数组存放学员姓名

2. 利用随机数获取学员下标

3. 通过下标获取学员姓名

4. 倒计时3秒通过for循环使用Thread.sleep(1000)来实现,

Thread.sleep(1000);此方法为静态方法,写在哪个线程中,哪个线程就休眠

package com.wz.thread06;

import java.util.Random;

public class test01 {
    /**
     * 知识点:线程的休眠
     * 需求:编写一个抽取学员回答问题的程序
     * 要求倒数三秒后输出被抽中的学员姓名
     */
    public static void main(String[] args) throws InterruptedException {
        //创建String数组存放学员姓名
        String[] names = {"张三","李四","王五","赵六","AAA","BBB","CCC"};
        //利用随机数获取学员下标
        Random random = new Random();
        int index = random.nextInt(names.length);
        //倒计时3秒通过for循环使用Thread.sleep(1000)来实现
        for (int i = 3; i >=1 ; i--) {
            System.out.println(i);
            Thread.sleep(1000);
        }
        //通过下标获取学员姓名
        System.out.println("抽到的学员是:"+names[index]);
    }
}

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_生产者消费者模型

2. 线程的礼让

需求:创建两个线程A,B,分别各打印1-100的数字,其中B一个线程,每打印一次,就礼让一次,观察实验结果

分析:

1. 创建A线程,继承Thread,重写run方法,打印1-100的数字

2. 创建B线程,继承Thread,重写run方法,打印1-100的数字,每打印一次,就礼让一次

Thread.yield();

此方法为静态方法,此方法写在哪个线程中,哪个线程就礼让

所谓的礼让是指当前线程退出CPU资源,并转到就绪状态,接着再抢

package com.wz.thread07;

public class A extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <=100 ; i++) {
            System.out.println("A线程"+i);
        }
    }
}
package com.wz.thread07;

public class B extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <=100 ; i++) {
            System.out.println("B线程"+i);
            Thread.yield();
        }
    }
}
package com.wz.thread07;

public class test01 {
    /**
     * 需求:创建两个线程A,B
     * 分别各打印1-100的数字
     * 其中B一个线程,每打印一次,就礼让一次,观察实验结果
     */
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        a.start();
        b.start();
    }
}

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_线程的休眠_02

3. 线程的合并

需求:主线程和子线程各打印200次,从1开始每次增加1,当主线程打印到10之后,让子线程先打印完再打印主线程

分析:

1. 创建主线程,打印1~200

2. 创建子线程,打印1~200

3. 判断当主线程打印到10,用join()方法将子线程加入主线程

t.join(); 合并方法

package com.wz.thread08;

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 1; i <=200 ; i++) {
            System.out.println("子线程"+i);
        }
    }
}
package com.wz.thread08;

public class test01 {
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        for (int i = 1; i <=200 ; i++) {
            System.out.println("主线程"+i);
            if (i>10){
                myThread.join();
            }
        }
    }
}

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_线程合并_03

4. 线程的中断

  1. stop();立即终止,该方法已经过时。无法保证功能的完整性
  2. run()执行完毕,利用boolean值来控制线程的中断
  3. interrupt();中断这个线程(改变线程状态)

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_生产者消费者模型_04

package com.wz.thread09;

public class MyThread extends Thread{
    @Override
    public void run() {
        //判断当前线程是否消亡(True-消亡 false- 未消亡)
        while (!Thread.currentThread().isInterrupted()){
            System.out.println("AAAA");
            System.out.println("BBBB");
            System.out.println("CCCC");
            System.out.println("DDDD");
            System.out.println("EEEE");
            System.out.println(Thread.currentThread().isInterrupted());
        }
    }
}
package com.wz.thread09;

public class test01 {
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        myThread.sleep(5000);
        //改变线程状态,开始为false(未消亡)--> 调用后 True(消亡)
        myThread.interrupt();
    }
}

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_线程合并_05

5. 后台线程(守护线程)

守护线程 默默守护着前台线程,当所有的前台线程都消亡后,守护线程会自动消亡

注意:垃圾回收器就是守护线程

t.setDaemon(true);

package com.wz.thread10;

public class A extends Thread{
    @Override
    public void run() {
        while (true){
            System.out.println("后台线程守护着前台线程!");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.wz.thread10;

public class test01 {
    public static void main(String[] args) throws InterruptedException {
        A a = new A();
        a.setDaemon(true);
        a.start();
        for (int i = 1; i <=20 ; i++) {
            System.out.println("前台线程"+i);
            Thread.sleep(1000);
        }
    }
}

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_线程的休眠_06

/**
	 * 重写
	 * 概念:父类方法在子类中重新写一遍
	 * 应用场景:父类方法不满足子类需求,考虑在子类中重写父类的方法
	 * 条件:
	 * 		1.在子类中重写
	 * 		2.返回值、方法名、参数列表、抛出异常类型必须和重写父类的方法的一致
	 * 		3.访问修饰符不能比父类更加严格
	 */

6. 线程的生命周期

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_线程的休眠_07

生产者消费者模型

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_线程的休眠_08

创建产品类(Phone)

package producer_consumer_01;

//产品类
public class Phone {

    private String brand;//品牌
    private double price;//价格
    private boolean store;//仓库-false空

    public Phone() {
    }

    public Phone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public boolean isStore() {
        return store;
    }

    public void setStore(boolean store) {
        this.store = store;
    }

    @Override
    public String toString() {
        return "Phone [brand=" + brand + ", price=" + price + "]";
    }
}

创建生产者线程Producer extends Thread,重写run()方法

package producer_consumer_01;

//生产者线程
public class Producer extends Thread{

    private Phone phone;

    public Producer(Phone phone) {
        this.phone = phone;
    }

    @Override
    public void run() {

        boolean flag = true;

        while(true){
            //加锁
            synchronized (phone) {
                if(phone.isStore()){
                    try {
                        phone.wait();//等待:1.将等待的线程记录在对象监视器中 2.释放锁资源 3.让当前线程进入到阻塞状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(flag){
                    phone.setBrand("华为");
                    phone.setPrice(3999);
                }else{
                    phone.setBrand("小米");
                    phone.setPrice(1999);
                }
                flag = !flag;
                phone.setStore(true);

                phone.notify();//唤醒:唤醒的对象监视器中随机的一个线程
            }
        }
    }
}

创建消费者线程 Consumer extends Thread,重写run()方法

package producer_consumer_01;

//消费者线程
public class Consumer extends Thread{

    private Phone phone;

    public Consumer(Phone phone) {
        this.phone = phone;
    }

    @Override
    public void run() {
        while(true){
            synchronized(phone){
                if(!phone.isStore()){
                    try {
                        phone.wait();//等待:1.将等待的线程记录在对象监视器中 2.释放锁资源 3.让当前线程进入到阻塞状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(phone.getBrand() + " -- " + phone.getPrice());
                phone.setStore(false);

                phone.notify();//唤醒:唤醒:唤醒的对象监视器中随机的一个线程
            }
        }
    }
}

测试类

package producer_consumer_01;

public class test01 {
    /**
     * 知识点:生产者消费者模型
     * 分析:
     * 		产品类
     * 		生产者线程不断的生产产品(set())
     * 		消费者线程不断的消费产品(get())
     *
     * 情况:一个生产者一个消费者的情况
     * 最终目的:生产一个、消费一个
     *
     * 步骤:
     * 		1.让生产者消费者线程操作同一个资源(产品对象)
     * 			bug:
     */
    public static void main(String[] args) {

        Phone phone = new Phone();

        Producer p = new Producer(phone);
        Consumer c = new Consumer(phone);

        p.start();
        c.start();
    }
}

2023年7月5日,生产者消费者模型,线程的休眠、礼让、合并、中断、生命周期、守护线程_生产者消费者模型_09

标签:String,Thread,void,phone,线程,2023,public,礼让
From: https://blog.51cto.com/u_15098423/6636194

相关文章

  • 2023-07-05:爱丽丝和鲍勃继续他们的石子游戏 许多堆石子 排成一行,每堆都有正整数颗石
    2023-07-05:爱丽丝和鲍勃继续他们的石子游戏许多堆石子排成一行,每堆都有正整数颗石子piles[i]游戏以谁手中的石子最多来决出胜负。爱丽丝和鲍勃轮流进行,爱丽丝先开始。最初,M=1。在每个玩家的回合中,该玩家可以拿走剩下的前X堆的所有石子,其中1<=X<=2M然后,令M=max......
  • day82(2023.7.5)
    1.什么是框架? ......
  • 每日总结2023年7月5日
    今日学习:页式存储(逻辑地址:页号+页内地址):逻辑地址和物理地址间的转换。优点:利用率高,便于管理。缺点:增加系统开销,可能产生抖动现象。段式存储(逻辑地址:段号+段内地址):优点:便于共享。缺点:内存利用率低。段页式存储:优点:空间浪费小,共享容易。缺点:增加软件复杂度,增加开销。块表:一块小容量......
  • 2023/7HL集训游记
    写在前面因为本人补题速度特别慢,所以博客随缘更新,其中还包括部分学术内容,纯享版指路Steven24博客。Day014时入眠,23时起床,一宿没睡,一直在开摆,顺便结束了斗破漫画的三刷,后来证明这是一个正确的选择,因为之后的几天都是断网状态。Day1上了飞机,还是很快就落地了,又是熟悉的夏天......
  • 2023.7.5
    快乐的一天从牛肉面开始,早上吃完东西后就去乡下的老家了,和舅舅约定好去钓鱼的,他还在忙着装修老房子呢,我就刷了一会儿手机,等到中午吃完饭才忙完,我带了我爸的渔具,舅舅可是个钓鱼行家,装备十分精良,钓了一下午,我只起了一条一斤的鲤鱼,他才厉害,钓了一条大的好像是2斤半的鲫鱼,总共加起来的......
  • 多线程介绍
    什么是程序?程序(Program)是一个静态的概念,一般对应于操作系统中的一个可执行文件。什么是进程?执行中的程序叫做进程(Process),是一个动态的概念。其实进程就是一个在内存中独立运行的程序空间。现代操作系统比如MacOSX,Linux,Windows等,都是支持“多任务”的操作系统,叫“多任务”呢?......
  • 2023.7.5
    1//2023.7.5周三2publicstaticvoidmain(String[]args)3{4//字符串连接符+5inta=10;6intb=20;7System.out.println(""+a+b);//输出:10208System.out.println(a+b+"");//输出:30910}11//java......
  • 2023-7-5 #64 短暂回归撕开色盘 拼凑回忆填补空白
    ——泠笙《多重妄想》442P7729交通运输(WormholeTransportaion)挺不错的题目。第一问较为简单,建图后,容易发现答案是\(m-2\)加最小环长度\(L\)。第二问先考虑环的部分分,问题即为:计数带标号无根树的数量,使得\(\sum\operatorname{dis}(i,i\bmodn+1)=2n-2\)。提\(n\)为根,......
  • 2023.7.5
    过了零点应该就算是今天了吧,所以说是在今天睡前了解到了p2p这个东西,听的一知半解但是很高兴能了解到它。今天准备学习,但是不多,似乎又被睡觉占领了大部分时间。上午又重新下了一个编译器,据说那个很好用。之后开始看《大道至简》,准备写读后感。但是中午清醒的大脑又被困倦占领,于......
  • 2023.7.5 杂题
    CF1174FEhabandtheBigFinale树链剖分。先s1求出\(x\)所在子树\(y\)。若\(y\)为\(1\)轻儿子,递归求解\(y\)。若\(y\)为重儿子,那么找到重链上与\(x\)深度相同的节点\(c\).调用dc,此时\(c\)向上跳\(x\)与\(c\)距离的一半便是\(lca\),递归求解。相当......