3.1线程的生命周期?
线程具有7个状态:出生状态,就绪状态,运行状态,等待状态,休眠状态,阻塞状态和死亡状态。
出生状态:用户创建线程处于的状态。
就绪状态:用户调用start方法后的状态。
运行状态:线程得到系统资源后就进入的状态。
等待状态:当处于运行状态下的线程调用Thread类中的wait()方法时,就会处于等待状态。
进入等待状态的线程必须调用Thread类中的notify()方法才能被唤醒,而notifyALL()方法是将所有处于等待状态下的线程唤醒。
休眠状态:当线程调用Thread类中的sleep()方法,则会进入休眠状态。
阻塞状态:如果一个线程在运行状态下发出输入/输出请求,该线程将进入阻塞状态,在其等待输入/输出结束时线程进入就绪状态。
对于阻塞的线程来说,即使系统资源空闲,线程依然不能回到运行状态。
死亡状态。当线程执行完run()方法时,线程处于死亡状态。
一旦进入可执行状态,就会在就绪与运行状态下辗转,同时也可能进入等待,休眠,阻塞和死亡状态。
备注:在同一时间点上,只有一个线程被执行。只是线程切换比较快,所以才有几个线程一起执行。
使线程进入就绪状态:
(1)调用sleep()方法
(2)调用wait()方法。
· (3)等待输入输出完成。
使线程处于就绪状态后,可以通过以后几种方式使线程再次进入运行状态(注意是再次):
(1)线程调用notify()方法。
(2)线程调用notifyAll()方法。
(3)线程调用interrupt()方法。
(4)线程的休眠时间结束。
(5)输入输出结束。
4.1线程的休眠
调用sleep()方法。sleep(毫秒数)方法就是定义该线程需要休眠的时间。
Thread。sleep(1000);表示让线程休眠1秒。
4.2线程的加入
在执行线程A的时候加入线程B的方法,使用Thread.join()方法。
如:
Thread A = new Thread(new Runnable(){
run(){
Thread.sleep(100);
B.join();
}
});
A.start();
Thread B = new Thread(new Runnable(){
run(){
执行的内容。
}
B.start();
})
4.3线程的中断
之前的版本会使用stop()方法停止线程,但是现在已经不用了。现在提倡在线程中写入一个无限循环,然后使用布尔型标记
控制循环的中断。
4.4线程的礼让
使用yield()方法表示礼让。它只是给当前正处于运行状态下的线程一个提醒,告知该线程可以将资源礼让给其他线程。
yield()方法使具有同样优先级的线程有进入可执行状态的机会,当当前线程放弃执行权的时候会再次进入就绪状态。对于
支持多任务的操作系统来说,不需要调用yield()方法,因为操作系统会为线程自动分配CPU时间片来执行。
5.1 线程的优先级
优先级越高就先执行那个线程,但这并不意味着低优先级的线程得不到运行,而只是它运行的概率较小,比如垃圾回收线程的优先级就较低。
线程的优先级在1~10之间,如果不在,会抛出IllegalArgumentException异常。
线程的优先级数越大,就越先执行,一般线程优先级都会默认为5.
可以使用Thread。setPriority("线程A的名字",优先级数,线程名称);
public void setPriority(String threadName,int priority,Thread t){
t.setPriority(priority);
t.setName(threadName);
t.start();
}
6.1线程安全
当多个线程处于同时执行状态时就会出现错误,如购票时就只有1张票了,当多个人去抢时就会出现票的个数出现负数。
6.2解决上述问题的方法,提出了线程同步机制
1.同步块
使用synchronized关键字。
如:建立时,run(){
while(true){
synchronized(""){
if(num > 0){
}
}}
}
备注:将资源放入同步块中,也被成为临界区,通常当其他线程获取到这个锁时,必须等待这个锁打开时才能使用。Object对象存在一个标志位,
并具有两个值0和1,一个线程的运行先检查该对象的标志位,如果为0状态,则存在其他线程在运行,这时该线程处于就绪状态,直到执行完该同步块中的
代码.如果该同步块处于1时,该线程可执行同步块中代码,并将Object对象标识位设置为0。
6.3使用同步方法
同步方法就是在方法面前修饰synchronized关键字的方法,语法:
synchronized void f() {}
当某个对象调用了同步方法,则该对象上的其他同步方法必须等待该同步方法执行完毕才能被执行。这是必须将每个能访问共享资源的方法修饰
为synchronized,否则会报错。