线程与进程
线程:进程中负责程序执行的执行单元,线程本身依靠程序进行运行,线程是程序中的顺序控制流,只能使用分配给程序的资源和环境。
进程:执行中的程序,一个进程至少包含一个线程。
可以将一个正在运行的.exe程序理解为一个进程
线程是进程中独立运行的子任务,比如QQ.exe有视屏线程、下载文件线程、传输数据线程等在后台默默的运行。线程允许在一个进程中存在多个程序控制流,线程会共享进程范围的资源,例如内存句柄和文件句柄,但每个线程都有各自的计数器、栈和局部变量等。线程可以看做一个基本的调度单位,如果没有明确的协同机制,那么线程将彼此独立运行。当一个线程访在使用一个变量,而另一个线程在同时访问这个变量时将造成不可预料的后果。
多线程的优点:充分使用cpu资源
如果任务一等待远程服务器返回数据,那么cpu就会一直处于等待状态任务二必须等任务一运行完之后才能运行,CPU利用率大幅度降低。
使用多线程
继承Thread类
创建好了自己的线程类之后,就可以创建线程对象了,然后通过start()方法去启动线程。注意,不是调用run()方法启动线程,run方法中只是定义需要执行的任务,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别
实现Runnable接口
Runnable的中文意思是“任务”,顾名思义,通过实现Runnable接口,我们定义了一个子任务,然后将子任务交由Thread去执行。注意,这种方式必须将Runnable作为Thread类的参数,然后通过Thread的start方法来创建一个新线程来执行该子任务。如果调用Runnable的run方法的话,是不会创建新线程的,这根普通的方法调用没有任何区别。
线程状态
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
常用方法
1、currentThread()返回当前代码段正在被哪个线程调用
2、isAlive()判断当前线程是否处于活动状态
3、sleep()方法在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)
4、getId()获取线程的唯一标识
5、yield()放弃当前的cpu资源,让给其他的任务占用cpu执行
停止线程
java中有三种方法可以终止正在运行的线程:
- 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
- 使用stop方法强行终止线程,但不推荐,stop会释放锁给数据造成不一致性的结果,stop和suspend以及resume一样,都是过期的方法,使用它们可能会产生不可预料的结果,
- 使用interrupt方法中断线程,但不会真的停止线程,而是在当前线程打了一个停止的标记。
判断线程是否中止:
this.interrupted:测试当前状态是否是中断状态,执行后具有将状态标志清除为false的功能。
this.isInterrupted测试线程Thread对象是否已经是中断状态,但不清除状态标志。
线程的优先级
线程的优先级分为1~10个等级,线程的优先级具有继承性,比如A线程启动了B线程,则B线程的优先级与A是一样的。setPriority()可以用来设置线程的优先级。优先级具有
守护线程
java线程有两种线程,一种是用户线程,另一种是守护线程。当进程转中不存在非守护线程时,守护线程自动销毁,典型的就是GC(垃圾回收器)线程。