当前位置: 首页 > news >正文

并发线程使用介绍(二)

2.2.6 线程的强占

Thread的非静态方法join方法
需要在某一个线程下去调用这个方法
如果在main线程中调用了t1.join(),那么main线程会进入到等待状态,需要等待t1线程全部执行完毕,在恢复到就绪状态等待
CPU调度。
如果在main线程中调用了t1.join(2000),那么main线程会进入到等待状态,需要等待t1执行2s后,在恢复到就绪状态等待CPU调
度。如果在等待期间,t1已经结束了,那么main线程自动变为就绪状态等待CPU调度。

public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("t1:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
for (int i = 0; i < 10; i++) {
System.out.println("main:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 1){
try {
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

2.2.7 守护线程

默认情况下,线程都是非守护线程
JVM会在程序中没有非守护线程时,结束掉当前JVM
主线程默认是非守护线程,如果主线程执行结束,需要查看当前JVM内是否还有非守护线程,如果没有JVM直接停止

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("t1:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.setDaemon(true);
t1.start();
}

2.2.8 线程的等待和唤醒

可以让获取synchronized锁资源的线程通过wait方法进去到锁的**等待池**,并且会释放锁资源
可以让获取synchronized锁资源的线程,通过notify或者notifyAll方法,将等待池中的线程唤醒,添加到**锁池**中
notify随机的唤醒等待池中的一个线程到锁池
notifyAll将等待池中的全部线程都唤醒,并且添加到锁池
在调用wait方法和notify以及norifyAll方法时,必须在synchronized修饰的代码块或者方法内部才可以,因为要操作基于某个对象
的锁的信息维护。

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
sync();
},"t1");
Thread t2 = new Thread(() -> {
sync();
},"t2");
t1.start();
t2.start();
Thread.sleep(12000);
synchronized (MiTest.class) {
MiTest.class.notifyAll();
}
}
public static synchronized void sync() {
try {for (int i = 0; i < 10; i++) {
if(i == 5) {
MiTest.class.wait();
}
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

2.3 线程的结束方式

线程结束方式很多,最常用就是让线程的run方法结束,无论是return结束,还是抛出异常结束,都可以

2.3.1 stop方法(不用)

强制让线程结束,无论你在干嘛,不推荐使用当然当然方式,但是,他确实可以把线程干掉

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();}
});
t1.start();
Thread.sleep(500);
t1.stop();
System.out.println(t1.getState());
}

2.3.2 使用共享变量(很少会用)

这种方式用的也不多,有的线程可能会通过死循环来保证一直运行。
咱们可以通过修改共享变量在破坏死循环,让线程退出循环,结束run方法

static volatile boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while(flag){
// 处理任务
}
System.out.println("任务结束");
});
t1.start();
Thread.sleep(500);
flag = false;
}

2.3.3 interrupt方式

共享变量方式

public static void main(String[] args) throws InterruptedException {
// 线程默认情况下, interrupt标记位:false
System.out.println(Thread.currentThread().isInterrupted());
// 执行interrupt之后,再次查看打断信息
Thread.currentThread().interrupt();
// interrupt标记位:ture
System.out.println(Thread.currentThread().isInterrupted());
// 返回当前线程,并归位为false interrupt标记位:ture
System.out.println(Thread.interrupted());
// 已经归位了
System.out.println(Thread.interrupted());
// =====================================================
Thread t1 = new Thread(() -> {
while(!Thread.currentThread().isInterrupted()){
// 处理业务
}
System.out.println("t1结束");
});
t1.start();
Thread.sleep(500);
t1.interrupt();
}

通过打断WAITING或者TIMED_WAITING状态的线程,从而抛出异常自行处理
这种停止线程方式是最常用的一种,在框架和JUC中也是最常见的

public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while(true){
// 获取任务
// 拿到任务,执行任务
// 没有任务了,让线程休眠
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("基于打断形式结束当前线程");
return;
}
}
});
t1.start();
Thread.sleep(500);
t1.interrupt();
}

wait和sleep的区别?
● 单词不一样。
● sleep属于Thread类中的static方法、wait属于Object类的方法
● sleep属于TIMED_WAITING,自动被唤醒、wait属于WAITING,需要手动唤醒。
● sleep方法在持有锁时,执行,不会释放锁资源、wait在执行后,会释放锁资源。
● sleep可以在持有锁或者不持有锁时,执行。 wait方法必须在只有锁时才可以执行。
wait方法会将持有锁的线程从owner扔到WaitSet集合中,这个操作是在修改ObjectMonitor对象,如果没有持有synchronized锁的
话,是无法操作ObjectMonitor对象的。

http://www.lryc.cn/news/229201.html

相关文章:

  • 【Proteus仿真】【51单片机】多路温度控制系统
  • 一些可以参考的文档集合15
  • k8s的service自动发现服务:实战版
  • 项目笔记记录
  • 【leetcode】1137. 第 N 个泰波那契数
  • 【解决】conda-script.py: error: argument COMMAND: invalid choice: ‘activate‘
  • Linux 性能调优之硬件资源监控
  • Windows系统隐藏窗口启动控制台程序
  • FreeSWITCH fail2ban.lua
  • Qt HTTP下载数据
  • 8. 深度学习——NLP
  • 部署 KVM 虚拟化平台
  • Juniper PPPOE双线路冗余RPM配置
  • 原生JS实现视频截图
  • 前端Rust二进制/wasm全平台构建流程简述
  • 加解密算法相关技术详解
  • Clickhouse学习笔记(13)—— Materialize MySQL引擎
  • 《QT从基础到进阶·二十四》按钮组QButtonGroup,单选框QRadioButton和多选框QCheckBox
  • Ansible--playbook剧本
  • MacOS下VMware Fusion配置静态IP
  • 三、机器学习基础知识:Python常用机器学习库(中文文本分析相关库)
  • Nginx 使用笔记大全(唯一入口)
  • 数据结构-二叉排序树(建立、查找、修改)
  • Linux 性能优化之使用 Tuned 配置优化方案
  • Day02_《MySQL索引与性能优化》
  • (只需三步)Vmvare tools安装教程,实现与windows互通复制粘贴与文件拖拽
  • Android自定义控件:一款多特效的智能loadingView
  • C语言之初阶指针
  • MongoDB基础知识~
  • 41. 缺失的第一个正数