七、java多线程基础的总结

一、干货

1.并发编程的三要素

<1>.原子性:原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。

<2>.可见性:可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。

<3>.有序性:有序性,即程序的执行顺序按照代码的先后顺序来执行。

2.实现可见性的方法有哪些

synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见性。

3.创建线程的三种方式的对比

<1>.采用实现Runnable、Callable接口的方式创建多线程。

优势:线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

劣势:编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

<2>.使用继承Thread类的方式创建多线程

优势:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

劣势:线程类已经继承了Thread类,所以不能再继承其他父类。

<3>.Runnable和Callable的区别

3.1).Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。

3.2).Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。

3.3).Call方法可以抛出异常,run方法不可以。

3.4).运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

4.线程的状态流转图

线程的生命周期及五种基本状态:

å²ä¸æ强å¤çº¿ç¨é¢è¯47é¢(å«ç­æ¡)ï¼å»ºè®®æ¶è

1)新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

2)就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

3)运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

4)阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。

根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5)死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

5.线程B怎么知道线程A修改了变量

1).volatile修饰变量

2).synchronized修饰修改变量的方法

3).wait/notify

4).while轮询(暂时没用过)

发布了122 篇原创文章 · 获赞 64 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/chenmingxu438521/article/details/103814238