线程
1、进程:一个独立执行的、包含有自身地址的程序→正在执行的程序。执行时间:CPU时间片。
线程:进程中的执行流程。线程→并发。java.lang.Thread类的对象实例。
2、构造方法:
public Thread()
:创建一个新的线程对象
public Thread(String ThreadName)
:名称为ThreadName的线程对象
3、创建新线程:定义一个类继承Thread类, 覆盖run()方法,再调用Thread类的start()方法,start()会产生一个新线程,该线程运行run()。start()使Thread实例变为线程。
Thread对象需要一个任务执行,任务是线程在启动时执行的工作,其功能代码在run()中。start()方法调用一个已启动的线程,则抛出异常IllegalThreadStateException。
public void run(){}
执行一个线程程序→自动产生线程。
main方法线程启动由JVM负责。
4、多线程:
public class Thread extends Object implements Runnable
:创建一个Thread对象并与Runnable对象相关联。构造方法:
public Thread(Runnable target)
public Thread(Runnable target,String name)
使用Runnable接口启动新线程的步骤:
①建立Runnable对象。
②用参数为Runnable对象的构造方法创建Thead实例。
③start()启动线程。
5、生命周期
出生:创建至start()调用前。
就绪/可执行
等待:notify()唤醒。
阻塞:运行时发出I/O请求。结束后进入就绪。即使资源空闲,也不能回到运行。
死亡:run()执行完毕。
○如何使线程进入就绪:sleep(),wait(),等待I/O结束。
○就绪→运行:notify(),notifyAll(),interrupt(),线程休眠结束,I/O结束。
6、进入休眠:Thread.sleep(long millis)
:millis单位是ms。
可能抛出异常:InterruptedException。
加入一新线程,当前线程暂停,新线程执行完毕后才继续执行原线程:join()
终止:run()无线循环,布尔值标记控制停止。
public void run(){
while(true){
...
if(isContinue) break;
}
}
boolean isContinue;
若线程调用了sleep(),wait()进入就绪。可用interrupt()离开run()并结束线程。程序抛出InterruptedException异常。
7、线程礼让:yield()
:提醒当前线程将资源让给别的线程。使相同优先级的进程有机会进入就绪。当前线程放弃执行权会进入就绪。
对于多任务操作系统不用yield(),操作系统会为线程自动分配CPU时间片。
8、优先级:取值范围:[Thread.MIN_PRIORITY,Thread.MAX_PRIORITY],对应常数[1,10]。默认是Thread.NORM_PRIORITY,对应常数5。每个新产生的线程继承父类的优先级。
每个线程的CPU时间片结束后,默认选当前优先级相同的线程运行。先高后低。
优先级低只是运行概率小。
如图,A、B轮换,都结束后→C,结束后→D。
setPriority()
:调整线程优先级。如果不在1-10内会抛IllegalArgumentException异常。
9、线程同步
资源访问冲突→共享资源上锁,只允许一个资源访问→同步机制。
同步块/临界区:synchronized(Object){}
Object:任意一个对象。有标志位0和1。线程运行到同步块时首先检查对象标志位,为0——同步块有其它线程运行中,当前线程处于就绪。其它线程结束运行后,标志位为1,轮到当前线程运行同步块代码,并将Object标志位置0,防其它线程。
同步方法:synchronized void f(){}