首页 > 其他分享 >线程简述:协程、抢占式、sleep、wait、interrupt,优雅中断线程,线程通信等

线程简述:协程、抢占式、sleep、wait、interrupt,优雅中断线程,线程通信等

时间:2024-05-30 14:28:38浏览次数:25  
标签:Runnable 协程 Thread 中断 线程 interrupt volatile wait

思维导图在此:

java 线程 简述-CSDN博客

1、线程与协程

协程-->线程-->进程,协程最小

协程:用户态,go语言

线程:用户态、内核态都有。cpu调度的最小单位。是工人,从进程获取资源,多个线程共享进程的资源。

进程:内核态。操作系统调度资源的最小单位。是资源管家。

2、调度机制

协同式。线程的切换由线程控制。A线程执行完再执行线程B。好处是没有线程同步问题,坏处是A出问题,后面会阻塞。

抢占式。线程的切换由操作系统控制。好处是不会阻塞,坏处是AB不一定谁先执行,且A可能还没执行完就切换到B了,有上下文转换。

java是抢占式,Thread.yeild()可以释放时间片,有上下文切换

3、如何创建线程

start() 和 run()

        // start是thread的方法,创建了线程,并执行runnable任务
        new Thread(runnable).start();
        // run是Runnable的方法,没有创建线程,只执行了任务
        new Thread(() -> System.out.println("只是一个lambda表达式创建的Runnable")).run(); 

4、如何创建任务

Runnable无返回值,不抛出异常

Callable有返回值,抛出异常

Callable底层是Runnable

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("只是一个Runnable");
            }
        };

        Runnable runnable1 = ()->System.out.println("只是一个lambda表达式创建的Runnable");

        Callable callable = new Callable() {
            @Override
            public Object call() throws Exception {
                return "这是一个callable";
            }
        };

5、java线程本质

java线程绑定jvm的线程(JVM Java Thread),jvm线程绑定操作系统的线程(OS Thread)。然后操作系统线程的状态与jvm线程的状态进行映射绑定

6、线程的几个方法

6.1、想让线程稍等一下

sleep(x):释放时间片(操作系统)、不释放锁(锁与线程无关)。x毫秒后开始竞争时间片

(注意:wait()是Object的方法,释放时间片,释放锁。锁和Object有关,Object中有记录所状态的字段)

yield():就是 sleep(0)

6.2、想让线程执行完再执行当前线程

join():main线程里写了A.join()代码。表示A先参加,即main会阻塞,等A线程执行完,再走main线程

6.3、想让线程停止

stop():释放时间片(马上停止线程),后面的代码不执行,不优雅,不推荐使用

interrupt():“中断”。更改状态,不释放时间片(不会停线程),中断标志位设为true

isInterrupted():“是否中断”。判断中断标志位是否是true

interrupted():“结束中断”。判断中断标志位是否是true,如果是true需要改为false(擦除)

6.4、如何优雅中断线程

  1. 设置中断状态
    使用Thread.interrupt()方法来设置线程的中断状态。这并不会立即停止线程,而是设置了一个中断请求标志。

  2. 检查中断状态
    被中断的线程应该周期性地检查其中断状态,通常通过Thread.currentThread().isInterrupted()方法。

  3. 响应中断
    当线程检测到中断请求时,它应该适当地响应。这通常意味着清理资源、保存状态,并优雅地终止。

  4. 不要使用Thread.stop()
    Thread.stop()方法已经被废弃,因为它可能导致线程留下不一致的状态。应该总是使用中断和协作机制来停止线程。

  5. 处理阻塞操作
    当线程在阻塞操作(如sleep()wait()join(), 或者某些I/O操作)上被中断时,这些操作会抛出InterruptedException。捕获这个异常,清除中断状态(如果需要),并适当地响应中断。

  6. 传递中断
    如果线程在调用其他可中断的阻塞方法时检测到中断,它应该清除自己的中断状态,并设置被调用线程的中断状态,以便后者也能响应中断。

7、线程通信

7.1、两个线程读取同一个变量

volatile:

Java中的volatile_java volatile-CSDN博客

底层:JMM、内存屏障、总线监听与缓存一致性协议

可见性:见到最新的数据。读时工作内存失效,获取主内存。写时工作内存马上刷新到主内存

有序性:和代码书写的顺序一样。禁止cpu优化指令重排。volatile写之前的读写操作不能重排在volatile写之后(和代码逻辑顺序一样)。volatile读之后的读写操作不能重排到volatile读之前(和代码逻辑顺序一样)。

管道:

用的不多

输入流和输出流进行绑定,形成管道。PipedWriter和PipedReader

B里创建管道变量

A = new thread(管道放进去)

B里操作管道变量,A里的管道变量会跟着变,这就实现了AB两个线程的通信,变量共享了,和volatile有点像

7.2、线程之间的阻塞和唤醒

wait()和notify()。Object的方法。涉及到锁,要在synchronize里面用wait,notify唤醒线程。

关键字wait和notify-CSDN博客

join() 、sleelp() 。Thread的方法,底层是wait(),notify()

 

 

 

标签:Runnable,协程,Thread,中断,线程,interrupt,volatile,wait
From: https://blog.csdn.net/Y_Tinty/article/details/139298210

相关文章

  • 在 Rust 多线程应用程序中锁定 Mutex 时发生死锁
    我正在开发一个Rust应用程序,其中有一个与PacketManager交互的BusDevice。在多线程环境中尝试锁定一个Mutex时,我遇到了死锁。应用程序被卡在锁定Mutex的那一行,再也无法继续。详细描述:在我的Rust应用程序中,我有一个使用PacketManager发送确认数据包的BusDevice。BusD......
  • 给师妹写的《Java并发编程之线程池十八问》被表扬啦!
    写在开头  之前给一个大四正在找工作的学妹发了自己总结的关于Java并发中线程池的面试题集,总共18题,将之取名为《Java并发编程之线程池十八问》,今天聊天时受了学妹的夸赞,心里很开心,毕竟自己整理的东西对别人起到了一点帮助,记录一下!Java并发编程之线程池十八问  经过之前......
  • kotlin基础之协程
    Kotlin协程(Coroutines)是Kotlin提供的一种轻量级的线程模型,它允许我们以非阻塞的方式编写异步代码,而无需使用回调、线程或复杂的并发API。协程是一种用户态的轻量级线程,它可以在需要时挂起和恢复,从而有效地管理资源,提高应用程序的响应性和性能。Kotlin协程的概念轻量级线程:协......
  • 【Rust】——使用消息在线程之间传递数据
    ......
  • C++ 跨线程 传递指针
    目录在C++中跨线程传递指针时,需要注意线程安全和生命周期管理的问题。以下是一些常见的方法,用于在C++中安全地跨线程传递指针:使用智能指针和线程安全队列结合使用std::shared_ptr和线程安全的队列(如std::queue配合互斥锁)是一种常见的方法。#include<iostream>#include<t......
  • C++ 线程同步condition_variable的使用
    一,condition_variable使用步骤创建一个scondition_variable对象。创建一个互斥量对象mutex。创建两个线程:等待线程和唤醒线程。在等待线程中,使用unique_lock锁定互斥量,并调用wait函数进入等待状态。在唤醒线程lock_guard锁定互斥量,并调用notify_one或notify_all函数唤醒等......
  • 线程练习题
    编写一个程序,主线程中创建一个子线程,容纳后让主线程先退出并返回一个值,子线程接合主线程后输出主线程的退出值,然后子线程退出./********************************************************************* filename:pthread.c* author :Dazz* date :2024/05/29*......
  • 协程 进程 线程的区别
    协程(Coroutine)、进程(Process)和线程(Thread)是三种并发编程的技术,它们在并发控制、资源使用和上下文切换方面有不同的特点和用途。以下是它们的主要区别:进程定义:进程是操作系统分配资源和调度的基本单位。每个进程拥有独立的地址空间、全局变量、堆和栈。资源开销:进程之间的切换......
  • 关于Interrupted system call 报错
    Socket编程或者其他的一些慢速系统调用中,我们经常会碰到“interruptedsystemcall”的问题。这些系统调用包括:长时间读取磁盘,等待网络连接i.e.Accept,阻塞的系统调用,i.e.Read/Writeepoll_wait/kevent这是因为系统调用在执行过程中有可能收到来自外部的信号中断,那么该系......
  • 多线程操作
    【一】threading模块开启线程的两种方式【1】直接调用ThreadfromthreadingimportThreadimporttimedeftask(name):print(f'{name}isstarting')time.sleep(3)print(f'{name}isending')defmain():t=Thread(target=task,args=("dr......