《JAVA多线程编程核心技术》 笔记:第一章
1.1、进程和线程的理解
1.2、同步和异步的理解(阻塞模式和非阻塞模式)
1.3 线程间共享变量和不共享变量
二、多线程的实现方式和构造方法:
2.1 实现方式:2个
2.2 构造方法:8个
三、线程的常用方法
3.1 start()方法
3.2 run()方法:让线程运行
3.3 sleep()方法:让线程休眠
3.4 suspend()方法和resume()方法:让线程暂停与恢复
3.5 .stop()方法:让线程停止(已废弃+不建议)
3.6 interrupt()方法:让线程停止(给线程打上停止标记)
注意:如何让线程停止
3.7 interrupted()方法 和 isInterrupted()方法
3.8 yield()方法:
四、线程安全和synchronized关键字
4.1 非线程安全产生的原因:
4.2 synchronized关键字的作用(解决线程安全问题)
五、Thread.currentThread()和this的区别:
六、线程的优先级:
七、END!
一、基本概念理解:
1.1、进程和线程的理解
进程:是受操作系统管理的基本运行单元。
线程:理解为在进程中独立运行的子任务。
注:Windows系统是多任务(进程)操作系统的。
1.2、同步和异步的理解(阻塞模式和非阻塞模式)
同步是阻塞模式,异步是非阻塞模式。
多线程是异步的。
我的理解:
同步是指两个线程的运行相关的,一个线程要阻塞等待另一个线程运行结束。
异步的意思是两个线程毫无相关,自己运行自己的。
1.3 线程间共享变量和不共享变量
不共享:每次新建一个线程对象即可,默认是不共享的。
共享:在创建需共享变量的多个线程时,传入同一个Runnable 对象,那么新建的线程将执行传入的Runnable 对象的run()方法。具体即为让一个线程执行另一个线程的run()方法。
二、多线程的实现方式和构造方法:
2.1 实现方式:2个
- 继承Thread类(JAVA单继承,有局限)
- 实现Runnable接口(建议使用)
2.2 构造方法:8个
其中两个可以接受一个 Runnable 对象,即可以把一个Runnable 对象(线程)当做入参传递给另一个线程。
这样,可以让一个线程执行另一个线程的run()方法。这样,执行对应run方法的线程就确定了(传入的线程)。
三、线程的常用方法
3.1 start()方法
start()方法:通知“线程规划器”此线程(相关信息和数据)已经准备就绪,等待调用线程对象的run()方法。具体何时调用,全部由系统管理。(执行的线程是系统的新线程,非当前线程)
3.2 run()方法:让线程运行
run()方法:可以直接让系统执行线程对象的run()方法(执行的线程是当前线程)。
否则,只是调用start()方法即可,具体执行由新线程执行。
3.3 sleep()方法:让线程休眠
让当前正在执行的线程休眠一段时间;
3.4 suspend()方法和resume()方法:让线程暂停与恢复
suspend()方法停止,resume()方法恢复。
不足:
- 会独占对象(即不释放锁),其他线程无法访问公共同步对象
- 不同步:即当前线程暂停,其他线程继续执行。导致数据不同步。
3.5 .stop()方法:让线程停止(已废弃+不建议)
可以使用Thread.stop()方法,但不建议,因为这个方法不是安全的,并且已被废弃。
建议使用:interrupt()方法(该方法不会终止一个正在运行的线程,需加入一个判断才可终止线程)
3.6 interrupt()方法:让线程停止(给线程打上停止标记)
并不是真的立即停止,只是在线程上打了一个停止的标记。具体什么时候停止,还需实际情况观察。(与start方法和run()方法的作用挺像)
注意:如何让线程停止
- 可以使用异常停止线程(比较建议的方法)
- 在沉睡中停止:先sleep()然后interrupt()。也可以先interrupt()后sleep()
- 暴力停止:使用stop() (不建议使用,因为会解锁,同时一些清理工作没有完成。会造成数据异常)
- interrupt()加上return。
- 线程正常退出;
注意,停止线程的问题在于线程停止后,不要执行其他代码,所以只要符合这个原则,实际实现可以自己设置。
3.7 interrupted()方法 和 isInterrupted()方法
interrupted()方法:测试当前线程(当前线程)是否已经是中断状态,执行后会将状态标志置清除为false;
isInterrupted()方法:测试线程Thread对象(调用该方法的线程对象所对应的线程,不一定是当前线程。例如在A线程中调用B线程对象的isInterrupted方法 )是否已经是中断状态,不清除状态标志;
参考: interrupt、interrupted 、isInterrupted 区别 - CSDN博客 https://blog.csdn.net/z69183787/article/details/25076033
3.8 yield()方法:
放弃当前的CPU资源,将它让给其他任务去占用CPU执行时间。
四、线程安全和synchronized关键字
4.1 非线程安全产生的原因:
- 线程A执行了一部分,然后暂停(线程A会保存当前执行环境);
- 此时线程B执行同样的部分,执行结束(线程B在线程A暂停时,修改了共用的数据。)
- 线程A继续执行(线程A以为还是原来的数据,继续执行。但数据已被线程B修改过。这就出现了线程不安全)
4.2 synchronized关键字的作用(解决线程安全问题)
synchronized可在任意对象及方法上加锁。当多个线程执行到该部分代码时,以排队方式进行处理。先判断要执行部分是否被加锁,如果被加锁,表明其他线程正在执行,需等其他线程执行完之后(即解锁),才能自己执行。
五、Thread.currentThread()和this的区别:
参考:Thread.currentThread()与this的区别 - CSDN博客 https://blog.csdn.net/qw222pzx/article/details/79353046
深入了解:可参考对于<对于start()方法和run()方法>这一部分的笔记
六、线程的优先级:
- 继承性:如A线程启动B线程,则B线程的优先级和A线程一样;
- 规则性:高优先级的线程总是大部分先执行完;(同时,当优先级差别很大时,线程的执行顺序与调用顺序无关)
- 随机性:优先级高的线程不一定每一次都先执行完;