目录
13.Thread.start()和Thread.run()区别
17.wait(),notify(),notifyall() 的作用是什么
进程是操作系统进行资源分配的最小单位,资源包括:CPU,内存空间,磁盘IO等。进程和进程之间是相互独立的
线程是CPU的最小调度单位,它比进程更小,线程共享一个进程下的资源,可以相互通信相互影响
在操作系统中,一个时间段内,有几个程序都处于启动到运行完毕,并且这几个程序都是在同一个处理机上运行 ,并发是指再一段时间内宏观上多个程序同时运行,多个任务抢占资源
当系统有一个以上的CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程。两个进程互不抢占资源,这种方式成为并行 。并行是指同一个时刻,多个任务真实运行互不影响,即多个任务不互相抢占资源
吞吐量指对网络 、设备、端口、虚电路或其他设施,单位时间内成功的传送数据的数量,网络吞吐量是指某个时刻,网络中两个节点间提供给网路应用的声音带宽,在没有帧丢失的情况下,设备能够接受的最大速率。
1)充分利用CPU的资源
市面上都是多CPU并支持多线程并发机制的,如果线程只在一个CPU核心中的一个线程中跑, 那么就浪费了CPU资源。就如同:计算机支持多个“车道”同时通车,如果你的程序只使用一个“车道”那么其他车道就属于闲置状态
2)加快相应用户的时间
当服务器收到一条请求后,多个线程再加不同的资源或者分别处理不同的任务, 那么势必会减少相应的速度,相应所读提高了,用户体检就会更好
3)将代码模块化异步化简单化
界面加载数据的时候可以分不同模块同时加载,每一个模块有可以独立设计
1)线程之间的安全问题
在同一个进程里的线程共享进程资源,那么就需要考虑资源使用的安全,比如:一个全局变量多个线程同时执行写操作,那么会出现程序问题,此时线程不安全。 因此,需要考虑线程同步保证线程安全
2)线程之间的死锁问题
Java为了解决线程之间的安全问题引入了锁机制。 如果不同的线程等待根本不可能释放的锁导致工作无法完成,我们称这种现象为线程死锁
当多个线程同时操作一个数据结构的时候,产生了相互修改和串行的情况,没有保证数据的一致性,通常称作这种代码未“线程不安全”。实际工作中,特别是Web项目Service和servlet一般都是单例的,在共享变量的情况下很容易出现线程不安全。
实现线程安全常见三种方法
1)继承Thread覆盖run方法
- public class MyThread extends Thread {
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- }
- }
2)实现Runable接口
- public class MyThread implements Runnable {
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- }
- }
3)实现Callable接口
- import java.util.concurrent.Callable;
-
- public class MyThread implements Callable{
-
- @Override
- public Object call() throws Exception {
- // TODO Auto-generated method stub
- return null;
- }
- }
Java线程中断是一种协作机制,中断并不能直接终止另一个线程,而需要被中断的线程自己处理,简单理解为线程有个boolean标识代表是否有中断请求,如果有,线程会在何时的时候自己处理中断请求,
例如:线程T1想中断T2, 只需要在T1中将T2的中断表示设置为true,然后T2可以选择在合适的时候处理中断请求,也可能不理会该请求
- //测试当前线程是否已经中断
- public static boolean interrupted();
-
- //测试线程是否已经中断,线程的中断状态不受该方法影响
- public boolean isInterrupted();
-
- //设置线程中断,是唯一能将中断状态设置为true的方法
- public void interrupt()
线程的生命周期一共有5个状态:new,runable,running,blocked,dead
start方法的作用是启动一个新线程,真正实现多线程,新线程会执行相应的run()方法。start()不能被重复调用。
run方法就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!
守护线程可以理解为后台运行的线程,进程结束,守护线程就会结束,不需要手动的取关心和通知其状态,在JVM的垃圾回收、内存管理的线程都是守护线程,还有比如数据库链接池的线程等
守护线程和普通线程没有太大区别,只需要调用线程对象setDeamon(true)方法将线程标记为守护线程
- //需要在线程启动前声明
- public final void setDeamon(boolean on)
synchronized是Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行这段代码,解决多线程“时序性问题” Synchronized是在JVM成名实现的,当代码出现异常的时候JVM自动释放,当只有少量竞争的时候,Synchronaized是很好的通用锁实现