线程的详解

  • 创建状态

  • 就绪状态

  • 阻塞状态

  • 运行状态

  • 死亡状态

  • 常用方法

    • setPriority(ing newPriority) 更改线程的优先级

    • sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠

    • join() 等待该线程终止

    • yield() 暂停当前正在执行的线程对象,并执行其他线程

    • interrupt() 中断线程,别用这个方式

    • isAlive() 测试线程是否处于活动状态

一、停止线程

  • 停止线程

    • 不推荐使用JDK提供的stop()、destroy()方法【已废弃】

    • 推荐线程自己停下来,利用次数,不建议死循环

    • 建议使用一个标志位进行终止变量,当flag=false,则终止线程进行

​
//测试stop
//1.建议线程正常停止 --->利用次数,不建议死循环
//2.建议使用标志位 --->设置一个标志位
//3.不要使用stop或者destroy等过时或者JDK不建议使用的方法
public class TestStop implements Runnable{
​//1.设置一个标识位private boolean flag =true;@Overridepublic void run() {int i =0;while (flag){System.out.println("run....Thread"+i++);}}
​//2.设置一个公开的方法停止线程,转换标志位public void stop(){this.flag=false;}
​public static void main(String[] args) {TestStop testStop = new TestStop();new Thread(testStop).start();
​for (int i = 0; i < 1000; i++) {System.out.println("main"+i);if(i==900){//调用stop方法切换标志位,让线程停止testStop.stop();System.out.println("线程该停止了");}}}
}

二、线程休眠

  • sleep(时间)指定当前线程阻塞的毫秒数

  • sleep存在异常InterruptedException

  • sleep时间达到后线程进入就绪状态

  • sleep可以模拟网络延时,倒计时等

  • 每一个对象都有一个锁,sleep不会释放锁

写到此处时,小铁锤的项目突然报错:Errors occurred while compiling module IDEA报错,于是小铁锤上到伟大的CSDN上找到了原因:项目创建时JDK版本选择错误啦,具体的修改步骤参考博客:Information:java: Errors occurred while compiling module IDEA报错_糖莱的博客-CSDN博客

//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable {//票数private int ticketNums =10;public void run() {while (true){if(ticketNums<=0){break;}//模拟延时try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}
​System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"票");}}
​public static void main(String[] args) {TestSleep testThread03 = new TestSleep();
​new Thread(testThread03,"小明").start();new Thread(testThread03,"老师").start();new Thread(testThread03,"黄牛党").start();}
}

public class TestSleep2 {public static void main(String[] args) {/*  try {tenDown();} catch (InterruptedException e) {e.printStackTrace();}*/
​//打印当前系统时间Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间while (true){try {Thread.sleep(1000);System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));startTime=new Date(System.currentTimeMillis());//更新当前时间} catch (InterruptedException e) {e.printStackTrace();}}}
​//模拟倒计时public static void tenDown() throws InterruptedException {int num =10;while (true){Thread.sleep(1000);System.out.println(num--);if(num<=0){break;}
​}}
}

三、线程礼让

  • 礼让线程,让当前正在执行的线程暂停,但不阻塞

  • 将线程从运行状态转为就绪状态

  • 让cpu重新调度,礼让不一定成功,看cpu心情

//礼让不一定成功,看cpu心情
public class TestYield {public static void main(String[] args) {MyYield myYield = new MyYield();
​new Thread(myYield,"铁锤").start();new Thread(myYield,"大王").start();}
}
​
class MyYield implements Runnable{
​@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"线程开始执行");Thread.yield();System.out.println(Thread.currentThread().getName()+"线程结束执行");}
}
​

四、Join

  • Join合并线程,待此线程执行完成后,再执行其他线程,其它线程阻塞

  • 可以想象成插队

//可以理解为插队
public class TestJoin implements Runnable{public static void main(String[] args) throws InterruptedException {
​//启动我们的线程TestJoin testJoin = new TestJoin();Thread thread = new Thread(testJoin);thread.start();
​//主线程for (int i = 0; i < 100; i++) {
​if(i==50){thread.join();//插队}System.out.println("main线程排队执行"+i);}}
​@Overridepublic void run() {for (int i = 0; i < 200; i++) {System.out.println("vip线程来了,统统闪开"+i);}}
}

五、线程状态观测

  • Thread.State

    线程状态。线程可以处于以下状态之一:

    • NEW

      尚未启动的线程处于此状态

    • RUNNABLE

      在Java虚拟机中执行的线程处于此状态

    • BLOCKED

      被阻塞等待监视器锁定的线程处于此状态

    • WAITING

      正在等待另一个线程执行特定动作的线程处于此状态

    • TIMED_WAITING

      正在等待另一个线程执行动作达到指定等待时间的线程处于此状态

    • TERMINATED

      已退出的线程处于此状态

一个线程可以在给定时间点处于一个状态。这些状态是不反映任何操作系统线程状态的虚拟机状态。

注意:线程一旦死亡,就不能再重启

public class TestState {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{for (int i = 0; i < 5; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}
​System.out.println("");});
​
​//观察状态Thread.State state = thread.getState();System.out.println(state);
​//观察启动后状态thread.start();//启动线程state=thread.getState();System.out.println(state);//Run
​while (state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态Thread.sleep(100);state=thread.getState();//更新线程状态System.out.println(state);//输出状态}}
}
​

六、线程的优先级

  • Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行

  • 线程的优先级用数字表示,范围从1~10

    • Thread.MIN_PRIORITY =1

    • Thread.MAX_PRIORITY =10

    • Thread.NORM_PRIORITY =5

  • 使用以下方式改变或获取优先级

    • getPriority

    • setPriority(int xxx)

//测试线程的优先级
public class TestPriority {public static void main(String[] args) {//主线程默认优先级无法更改System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
​MyPriority myPriority = new MyPriority();
​Thread thread1 = new Thread(myPriority, "线程1");Thread thread2 = new Thread(myPriority, "线程2");Thread thread3 = new Thread(myPriority, "线程3");Thread thread4 = new Thread(myPriority, "线程4");Thread thread5 = new Thread(myPriority, "线程5");Thread thread6 = new Thread(myPriority, "线程6");
​//先设置优先级再启动thread1.start();
​thread2.setPriority(1);thread2.start();
​
​thread3.setPriority(4);thread3.start();
​
​thread4.setPriority(Thread.MAX_PRIORITY);//MAX_PRIORITY=10thread4.start();
​
​}
}
​
class MyPriority implements Runnable{
​@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());}
}
​

七、守护(daemon)线程

  • 线程分为用户线程和守护线程

  • 虚拟机必须确保用户线程执行完毕

  • 虚拟机不用等待守护线程执行完毕

  • 如后台记录操作日志,监控内存,垃圾回收等待

//测试守护线程
//上帝守护你
public class TestDaemon {
​public static void main(String[] args) {God god = new God();
​Thread thread = new Thread(god);thread.setDaemon(true);//默认是false表示是用户线程,正常的线程都是用户线程,true表示守护线程thread.start();//上帝守护线程启动
​new Thread(new You()).start();//你 用户线程启动}
}
​
//上帝
class God implements Runnable{
​@Overridepublic void run() {while(true){System.out.println("上帝保佑着你");}}
}
​
​
//你
class You implements Runnable{
​@Overridepublic void run() {for (int i = 0; i < 36500; i++) {System.out.println("你一生都开心的活着");}System.out.println("====goodBye!world!====");}
}
​

八、线程的同步机制

发生在多个线程操作同一个资源

  • 并发:同一个对象被多个线程同时操作

  • 现实生活中,我们会遇到“同一个资源,多个人都想使用”的问题,比如,食堂排队打饭,每个人都想吃饭,最天然的解决办法就是:排队,一个一个来

  • 处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这时候我们就需要线程同步,线程同步其实就是一种等待机制。多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用

  • 形成条件:队列+锁---》安全性

  • 由于同一个进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制synchronized,当一个线程获得对象的拍它锁,独占资源,其他线程必须等待,使用后释放锁即可,存在以下问题:

    • 一个线程持有锁会导致其他所有需要此锁的线程挂起

    • 在多线程竞争下,加锁,释放锁会导致比较多的上下文切换和调度延时,引起性能问题

    • 如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能问题

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

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

相关文章

【Linux进行时】进程地址空间

进程地址空间 例子引入&#xff1a; 我们在讲C语言的时候&#xff0c;老师给大家画过这样的空间布局图&#xff0c;但是我们对它不了解 我们写一个代码来验证Linux进程地址空间 #include<stdio.h> #include<assert.h> #include<unistd.h> int g_value100; …

Chrome之解决DevTools: Failed to load data:No resource with given identifier found

问题 使用DevTools抓包时候, 有些跨域请求无法在加载出来, 提示 Failed to load data:No resource with given identifier found 解决办法 换其他浏览器 下断点 打开DevTools, 选择源代码/来源/Sources,找到事件监听器断点/Event Listener Breakpoints, 找到加载/Load下面…

<学习笔记>从零开始自学Python-之-常用库篇(十二)Matplotlib

Matplotlib 是Python中类似 MATLAB的绘图工具&#xff0c;Matplotlib是Python中最常用的可视化工具之一&#xff0c;可以非常方便地创建2D图表和一些基本的3D图表&#xff0c;可根据数据集&#xff08;DataFrame&#xff0c;Series&#xff09;自行定义x,y轴&#xff0c;绘制图…

云可观测性安全平台——掌动智能

云可观测性安全平台是一个跨架构、跨平台的可观测性方案&#xff0c;实现对云环境下的细粒度数据可视化&#xff0c;满足安全部门对云内部安全领域的多场景诉求&#xff0c;包括敏感数据动态监管、云网攻击回溯分析、攻击横移风险监控、云异常流量分析。本文将介绍掌动智能云可…

【ldt_struct】0ctf2021-kernote

前言 题目给的文件系统是 ext4&#xff0c;所以我们只需要将其挂载即可使用&#xff1a; 1、创建一个空目录 2、使用 mount 将其挂载即可 3、使用 umount 卸载即可完成打包 开启了 smap、smep、kaslr 和 kpti 保护&#xff0c;并且给了如下内核编译选项&#xff1a; Her…

java web+Mysql e-life智能生活小区物业管理系统

本项目为本人自己书写&#xff0c;主要服务小区业主和管理人员。 e-life智能生活小区涉及多个方面的智能化和便利化服务&#xff1a; 1. 用户模块&#xff1a;包含基本的登入登出操作&#xff0c;查看个人信息中用户可以查看 自己的个人资料但不可以修改个人信息。 a) 用户…

聊聊分布式架构——序列化和反序列化

目录 序列化与反序列化 为什么需要序列化 常见的序列化方式 java的序列化示例 transient排除序列化 Java序列化的简单总结 序列化与反序列化 序列化就是把对象的状态信息转化为可存储或传输的形式过程&#xff0c;也就是把对象转化为字节序列的过程称为对象的序列化。 反…

Docker快速搭建漏洞靶场指南

user: admin passwrod&#xff1a;password 查看容器是否已开启&#xff1a; 最常见漏洞&#xff1a; 防护级别提高后&#xff1a; 更改防护级别&#xff1a; 复现vulhub漏洞靶场&#xff1a; 开启&#xff1a; 一个是漏洞类型一个是真实的漏洞靶场。

去雨去雪去雾算法之本地与服务器的TensorBoard使用教程

在进行去雨去雾去雪算法实验时&#xff0c;需要注意几个参数设置&#xff0c;num_workers只能设置为0&#xff0c;否则会报各种稀奇古怪的错误。 本地使用TensorBoard 此外&#xff0c;发现生成的文件是events.out.tfevents格式的&#xff0c;查询了一番得知该文件是通过Tens…

asp.net core mvc 文件上传,下载,预览

//文件上传用到了IformFile接口 1.1文件上传视图 <form action"/stu/upload" method"post" enctype"multipart/form-data"><input type"file" name"img" /><input type"submit" value"上传&…

Lwip的接收邮箱大小的影响

LwIP&#xff08;Lightweight IP&#xff09;是一个用于嵌入式系统的轻量级的TCP/IP协议栈&#xff0c;它支持UDP和其他网络协议。 接收邮箱大小 在LwIP中&#xff0c;UDP接收邮箱的大小对系统性能和可靠性有一定影响。 首先&#xff0c;UDP接收邮箱的大小决定了可以同时接收…

联想Lenovo 威6 15-ITL(82F2)原厂Win10系统

lenovo联想原装出厂系统 自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 下载链接&#xff1a;https://pan.baidu.com/s/1darORHmIyAXkD7HvKRNHNw?pwddh6e 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff1a;11.…