多线程与并发编程【线程休眠、线程让步、线程联合、判断线程是否存活】(二)-全面详解(学习总结---从入门到深化)

news/2024/5/6 9:22:12/文章来源:https://blog.csdn.net/m0_58719994/article/details/131648197

 

 

目录

线程休眠

线程让步

线程联合

Thread类中的其他常用方法

判断线程是否存活

线程的优先级


 

线程休眠

 sleep()方法:可以让正在运行的线程进入阻塞状态,直到休眠时间 满了,进入就绪状态。sleep方法的参数为休眠的毫秒数。

public class SleepThread implements Runnable
{@Overridepublic void run() {     System.out.println(Thread.currentThread().getName()+" 线程开始");for(int i=0;i<20;i++){System.out.println(Thread.currentThread().getName()+" "+i);try {//线程休眠1秒Thread.sleep(1000);} catch(InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+" 线程结束");}public static void main(String[] args) {System.out.println("主线程开始");Thread t = new Thread(newSleepThread());t.start();System.out.println("主线程结束");}
}

线程让步

 yield()让当前正在运行的线程回到就绪状态,以允许具有相同优先 级的其他线程获得运行的机会。因此,使用yield()的目的是让具有 相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保 证yield()达到让步的目的,因为,让步的线程可能被线程调度程序 再次选中。

 使用yield方法时要注意的几点:

      1 yield是一个静态的方法。

      2 调用yield后,yield告诉当前线程把运行机会交给具有相同优先级的线程。

      3 yield不能保证,当前线程迅速从运行状态切换到就绪状态。

      4 yield只能是将当前线程从运行状态转换到就绪状态,而不能是等待或者阻塞状态。

public class TestyieldThread implements Runnable {@Overridepublic void run() {for(int i=0;i<30;i++){if("Thread0".equals(Thread.currentThread().getName())){if(i == 0){Thread.yield();}}System.out.println(Thread.currentThread().getName()+" "+i);}}public static void main(String[] args) {Thread t1 = new Thread(newTestyieldThread());Thread t2 = new Thread(newTestyieldThread());t1.start();t2.start();}
}

线程联合

 当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结 束之前,当前线程不能再次执行。线程A在运行期间,可以调用线程 B的join()方法,让线程B和线程A联合。这样,线程A就必须等待线 程B执行完毕后,才能继续执行。

 join方法的使用

join()方法就是指调用该方法的线程在执行完run()方法后,再执行 join方法后面的代码,即将两个线程合并,用于实现同步控制。 

class A implements Runnable{private Thread b;public A(Thread b){this.b = b;}@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+" A "+i);if(i == 5){try {this.b.join();} catch(InterruptedException e) {e.printStackTrace();}}try {Thread.sleep(1000);} catch (InterruptedException e){e.printStackTrace();}}}
}
class B implements Runnable{@Overridepublic void run() {for(int i=0;i<20;i++){System.out.println(Thread.currentThread().getName()+" B "+i);try {Thread.sleep(1000);} catch (InterruptedException e){e.printStackTrace();}}}
}
public class TestJoinThread {public static void main(String[] args) {Thread t1 = new Thread(new B());Thread t = new Thread(new A(t1));t.start();t1.start();for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+" "+i);if(i ==2){try {t.join();} catch(InterruptedException e) {e.printStackTrace();}}try {Thread.sleep(1000);} catch (InterruptedException e){e.printStackTrace();}}}
}

线程联合案例

需求: 实现爸爸让儿子买烟。

/**
* 儿子买烟线程
*/
class SonThread implements Runnable{@Overridepublic void run() {System.out.println("儿子出门买烟");System.out.println("儿子买烟需要10分钟");for(int i=0;i<10;i++){System.out.println("第"+i+"分钟");try {Thread.sleep(1000);} catch (InterruptedException e){e.printStackTrace();}}System.out.println("儿子买烟回来了");}
}
/**
* 爸爸抽烟线程
*/
class FatherThread implements Runnable{@Overridepublic void run() {System.out.println("爸爸想抽烟,发现烟抽完了");System.out.println("爸爸让儿子去买一包红塔山");Thread t = new Thread(new SonThread());t.start();System.out.println("等待儿子买烟回来");try {t.join();} catch (InterruptedException e) {e.printStackTrace();System.out.println("爸爸出门找儿子");System.exit(1);}System.out.println("爸爸高兴的接过烟,并把零钱给了儿子");}
}
public class TestJoinDemo {public static void main(String[] args) {System.out.println("爸爸和儿子买烟的故事");Thread t = new Thread(new FatherThread());t.start();}
}

Thread类中的其他常用方法

获取当前线程名称

方式一 this.getName()获取线程名称,该方法适用于继承Thread实现多线 程方式。

class GetName1 extends Thread{@Overridepublic void run() {System.out.println(this.getName());}
}

方式二 Thread.currentThread().getName()获取线程名称,该方法适用于 实现Runnable接口实现多线程方式。

class GetName2 implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}

设置线程的名称

方式一 通过构造方法设置线程名称。

class SetName1 extends Thread{public SetName1(String name){super(name);}@Overridepublic void run() {System.out.println(this.getName());}
}
public class SetNameThread {public static void main(String[] args) {SetName1 setName1 = new SetName1("SetName1");setName1.start();}
}

方式二 通过setName()方法设置线程名称。

class SetName2 implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}
public class SetNameThread {public static void main(String[] args) {Thread thread = new Thread(new SetName2());thread.setName("SetName2");thread.start();}
}

判断线程是否存活

 isAlive()方法: 判断当前的线程是否处于活动状态。 活动状态是指线程已经启动且尚未终止,线程处于正在运行或准备 开始运行的状态,就认为线程是存活的。

class Alive implements  Runnable{@Overridepublic void run() {for(int i=0;i<4;i++){System.out.println(Thread.currentThread().getName()+" "+i);try {Thread.sleep(500);} catch (InterruptedException e){e.printStackTrace();}}}
}
public class TestAliveThread {public static void main(String[] args) {Thread thread = new Thread(newAlive());thread.setName("Alive");thread.start();System.out.println(thread.getName()+" "+thread.isAlive());try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(thread.getName()+""+thread.isAlive());}
}

线程的优先级

 什么是线程的优先级

每一个线程都是有优先级的,我们可以为每个线程定义线程的优先 级,但是这并不能保证高优先级的线程会在低优先级的线程前执 行。线程的优先级用数字表示,范围从1到10,一个线程的缺省优 先级是5。 Java 的线程优先级调度会委托给操作系统去处理,所以与具体的操 作系统优先级有关,如非特别需要,一般无需设置线程优先级。

注意

线程的优先级,不是说哪个线程优先执行,如果设置某个线程 的优先级高。那就是有可能被执行的概率高。并不是优先执 行。

 线程优先级的使用

使用下列方法获得或设置线程对象的优先级。

1 int getPriority();

2 void setPriority(int newPriority);

注意:优先级低只是意味着获得调度的概率低。并不是绝对先 调用优先级高的线程后调用优先级低的线程。

class Priority implements Runnable{private int num = 0;private  boolean flag = true;@Overridepublic void run() {while(this.flag){System.out.println(Thread.currentThread().getName()+" "+num++);}}public void stop(){  this.flag = false;}
}
public class PriorityThread {public static void main(String[] args)throws Exception {Priority p1 = new Priority();Priority p2 = new Priority();Thread t1 = new Thread(p1,"线程1");Thread t2 = new Thread(p2,"线程2");System.out.println(t1.getPriority());//Thread.MAX_PRIORITY = 10t1.setPriority(Thread.MAX_PRIORITY);//Thread.MAX_PRIORITY = 1t2.setPriority(Thread.MIN_PRIORITY);t1.start();t2.start();Thread.sleep(1000);p1.stop();p2.stop();}
}

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

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

相关文章

两部搞定Pytorch 安装与配置(小白也能搞定!!!)

Pytorch 安装与配置 NVIDIA系统管理界面查看 nvidia-smi 进入NVIDIA系统管理界面 对应的详细解释看下图 参考博文 (53条消息) nvidia-smi命令详解和一些高阶技巧介绍_Chaos_Wang_的博客-CSDN博客 CUDA 查看 CUDA 有两类&#xff1a;其中一类是驱动API(Driver API)&#xff…

实现windows系统文件传输到Linux系统中的工具

1、实现windows系统文件传输到Linux系统中的工具 yum -y install lrzsz然后就可以将windows中的文件&#xff0c;直接拖到Xshell窗口即可。

【钱处理】商业计算怎样才能保证精度不丢失

以项目驱动学习&#xff0c;以实践检验真知 前言 很多系统都有「处理金额」的需求&#xff0c;比如电商系统、财务系统、收银系统&#xff0c;等等。只要和钱扯上关系&#xff0c;就不得不打起十二万分精神来对待&#xff0c;一分一毫都不能出错&#xff0c;否则对系统和用户来…

Kafka入门,mysql5.7 Kafka-Eagle部署(二十五)

官网 https://www.kafka-eagle.org/ 下载解压 这里使用的是2.0.8 创建mysql数据库 创建名为ke数据库,新版本会自动创建&#xff0c;不会创建的话&#xff0c;自己手动创建&#xff0c;不然会报查不到相关表信息错误 SET NAMES utf8; SET FOREIGN_KEY_CHECKS 0;-- ------…

拥有铁粉,怀抱CSDN大家庭

&#x1f451; 个人主页 &#x1f451; &#xff1a;&#x1f61c;&#x1f61c;&#x1f61c;Fish_Vast&#x1f61c;&#x1f61c;&#x1f61c; &#x1f41d; 个人格言 &#x1f41d; &#xff1a;&#x1f9d0;&#x1f9d0;&#x1f9d0;说到做到&#xff0c;言出必行&am…

python_day4

def test():return 1, a, Truex, y, z test() print(f"x{x},y{y},z{z}")位置参数&#xff1a;调用时根据参数位置传递参数 关键字参数&#xff1a;调用时通过“键值”形式传参 def user(name, age, gender):print(f"name:{name},age:{age},gender:{gender}&q…

图床项目之公网发布和测试

项目发布和测试 一、http服务测试1.1、ab http压力测试1.2、post测试&#xff08;注册请求和登录请求&#xff09; 二、性能测试2.1、生成测试脚本2.2、上传测试2.2.1、单客户端测试本地上传到本机服务器2.2.2、如果使用集群的方式进行测试 2.3、下载测试2.4、删除测试2.5、测试…

springboot请求重定向失败问题解决方案

今天晚上在写登录页面时&#xff0c;发现自己的首页无法正常访问&#xff0c;用户名和密码正常的情况下还是无法访问首页。于是开始进行debug&#xff0c; 程序执行至此处时无任何异常&#xff0c;但是就是在进行重定向页面时出现了404&#xff0c;在检查导航栏后发现地址栏也发…

深度学习——批数据训练

代码与详细注释&#xff1a; BATCH_SIZE 5&#xff0c;shuffleTrue import torch import torch.utils.data as Data# 添加随机种子以使结果可复现 torch.manual_seed(1) # reproducible# 批大小 BATCH_SIZE 5 # BATCH_SIZE 8x torch.linspace(1, 10, 10) # this…

dvwa靶场通关(九)

第九关&#xff1a;Weak Session IDs&#xff08;弱会话IDs&#xff09; 当用户登录后&#xff0c;在服务器就会创建一个会话(session)&#xff0c;叫做会话控制&#xff0c;接着访问页面的时候就不用登录&#xff0c;只需要携带 Sesion去访问。 sessionID作为特定用户访问站…

用技术指标伦敦金行情走势图

经常有投资者说&#xff0c;伦敦金行情走势图老是涨跌涨跌&#xff0c;抓不准它涨跌的规律&#xff0c;老是被它弄得头昏脑胀。其实看伦敦金行情走势图的方法有很多&#xff0c;最直接的就是使用技术指标。技术指标本来就是投资者为了避免伦敦金行情走势图上价格干扰性波动&…

什么是热修复?它的优缺点是什么?

我们开发时常常要考虑的一些问题。 开发上线的版本能保证不存在Bug么&#xff1f; 修复后的版本能保证用户都及时更新么&#xff1f; 如何最大化减少线上Bug对业务的影响&#xff1f; 热修复技术帮助我们解决了很多问题&#xff0c;带来的优势不言而喻。不知道各位对于热修复技…

【AcWing算法基础课】第四章 数学知识(未完待续)

文章目录 前言课前温习番外&#xff1a;秦九韶算法核心模板 一、质数1. 试除法判定质数核心模板1.1题目描述1.2思路分析1.3代码实现 2、试除法分解质因数核心模板1.4题目描述1.5思路分析1.6代码实现 二、筛素数1.朴素筛法求素数核心模板2.线性筛法求素数&#xff08;O(n)&#…

vue拼接html中onclick的触发方式,模版字符串拼接点击事件在vue项目中不生效问题

模版字符串拼接点击事件在vue项目中不生效问题 下面的点击事件没有任何效果&#xff0c;但是如果换成onclick绑定事件则会提示没有该方法。主要原因是&#xff1a; 模版字符串中拼接的html片段中的方法调不到vue中this.methods里的东西&#xff0c;因为methods里的代码是编译…

STM32 Proteus UCOSII系统多路数据采集系统8路开关量4路电压-0058

STM32 Proteus UCOSII系统多路数据采集系统8路开关量4路电压-0058 Proteus仿真小实验&#xff1a; STM32 Proteus UCOSII系统多路数据采集系统8路开关量4路电压-0058 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD1602显示器8路光耦隔离开关量采集4路微小信号…

你的流量虚了吗?分析手机流量卡不足量的套路

当今时代&#xff0c;手机流量的使用是每个人每天都在消耗的事情&#xff0c;在有WIFI的情况下还好&#xff0c;大家不需要担心流量用多了还是少了&#xff0c;但是在使用手机流量的时候&#xff0c;就需要注意了&#xff0c;看看是不是会用超什么的&#xff0c;但是现在有一个…

网络编程5——TCP协议的五大效率机制:滑动窗口+流量控制+拥塞控制+延时应答+捎带应答

文章目录 前言一、TCP协议段与机制TCP协议的特点TCP报头结构TCP协议的机制与特性 二、TCP协议的 滑动窗口机制 三、TCP协议的 流量控制机制 四、TCP协议的 拥塞控制机制 五、TCP协议的 延时应答机制 六、TCP协议的 捎带应答机制 总结 前言 本人是一个普通程序猿!分享一点自己的…

QT事件处理

设计一个闹钟&#xff0c;定时播报内容。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTimerEvent> #include <QDateTime> #include <QMessageBox> #include <QTextToSpeech> #include <QDebug> namespa…

41. 同时在线人数问题

文章目录 题目需求思路一实现一学习链接题目来源 题目需求 现有各直播间的用户访问记录表&#xff08;live_events&#xff09;如下。 表中每行数据表达的信息为&#xff1a;一个用户何时进入了一个直播间&#xff0c;又在何时离开了该直播间。 现要求统计各直播间最大同时在…

21-注册中心与配置中心Nacos

已经使用过了Spring cloud提供的Geteway、openFeign。 1、注册中心与配置中心 1.1、注册中心 相当于通讯录,让应用之间相互认识。 用途: 实例的健康检查。 路由转发:为了控制成本,会对机器做动态扩容,此时IP就不固定了。 远程调用。 1.2、配置中心 动态修改线上的配…