原博文地址:http://www.cnblogs.com/dolphin0520/p/3920357.html
1.線程的狀態:new(創建)->runnable(就緒)->running(運行),運行時又分狀態:阻塞(blocked),time waiting(睡眠或等待一定的事件),waiting(等待被喚醒)。
線程執行完畢,或者突然中斷,進入dead(死亡or銷燬)狀態。如下圖所示:
2.Thread之sleep()方法:
1)sleep相當於讓線程睡眠,交出CPU,讓CPU去執行其他的任務。
2)sleep方法不會釋放鎖,也就是說如果當前線程持有對某個對象的鎖,則即使調用sleep方法,其他線程也無法訪問這個對象。
例子如下:
public class Threadsleep {
private int i = 10;
private Object object = new Object();
public static void main(String[] args) throws IOException {
Threadsleep threadsleep = new Threadsleep();
//下面兩個線程共享threadsleep對象
MyThread thread1 = threadsleep.new MyThread();
MyThread thread2 = threadsleep.new MyThread();
thread1.start();
thread2.start();
}
class MyThread extends Thread{
@Override
public void run() {
synchronized (object) {
i++;
System.out.println("i:"+i);
try {
System.out.println("線程"+Thread.currentThread().getName()+"進入睡眠狀態");
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("線程"+Thread.currentThread().getName()+"睡眠結束");
i++;
System.out.println("i:"+i);
}
}
}
}
結果:
結論:當Thread-0進入睡眠狀態之後,Thread-1並沒有去執行具體的任務。只有當Thread-0執行完之後,此時Thread-0釋放了對象鎖,Thread-1纔開始執行。
3.Thread之join()方法:
join()
join(long millis) //參數爲毫秒
join(long millis,int nanoseconds) //第一參數爲毫秒,第二個參數爲納秒
1)假如在main線程中,調用thread.join方法,則main方法會等待thread線程執行完畢或者等待一定的時間。
2)如果調用的是無參join方法,則等待thread執行完畢,如果調用的是指定了時間參數的join方法,則等待一定的事件。
例子如下:
public class Threadjoin {
public static void main(String[] args) throws IOException {
System.out.println("進入線程"+Thread.currentThread().getName());
Threadjoin threadjoin = new Threadjoin();
MyThread thread1 = threadjoin.new MyThread();
thread1.start();
try {
System.out.println("線程"+Thread.currentThread().getName()+"等待");
thread1.join();
System.out.println("線程"+Thread.currentThread().getName()+"繼續執行");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class MyThread extends Thread{
@Override
public void run() {
System.out.println("進入線程"+Thread.currentThread().getName());
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("線程"+Thread.currentThread().getName()+"執行完畢");
}
}
}
結果:
結論:1)當調用thread1.join()方法後,main線程會進入等待。然後等待thread1執行完之後再繼續執行。
2)thread1.join()後讓main線程進入阻塞狀態,並且會釋放線程佔有的鎖,並交出CPU執行權限。
4.Thread之interrupt方法:
1)interrupt,顧名思義,即中斷的意思。
2)單獨調用interrupt方法可以使得處於阻塞狀態的線程拋出一個異常,也就說,它可以用來中斷一個正處於阻塞狀態的線程。
例子如下:
public class Threadinterrupt {
public static void main(String[] args) throws IOException {
Threadinterrupt threadinterrupt = new Threadinterrupt();
MyThread thread = threadinterrupt.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
try {
System.out.println("進入睡眠狀態");
Thread.currentThread().sleep(10000);
System.out.println("睡眠完畢");
} catch (InterruptedException e) {
System.out.println("得到中斷異常");
}
System.out.println("run方法執行完畢");
}
}
}
結果:
結論:1)interrupt方法可以中斷處於阻塞狀態的線程。
問題:interrupt能不能中斷處於非阻塞狀態的線程呢?如下例子:
public class Threadinterrupt2 {
public static void main(String[] args) throws IOException {
Threadinterrupt2 threadinterrupt2 = new Threadinterrupt2();
MyThread thread = threadinterrupt2.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
int i = 0;
while(i<Integer.MAX_VALUE){
System.out.println(i+" while循環");
i++;
}
}
}
}
結論:通過測試結果,發現直接調用interrupt方法不能中斷正在運行中的線程。
問題:如何中斷正在運行的線程呢?
1)一般會在MyThread類中增加一個屬性 isStop來標誌是否結束while循環,然後再在while循環中判斷isStop的值。如下:
class MyThread extends Thread{
private volatile boolean isStop = false;
@Override
public void run() {
int i = 0;
while(!isStop){
i++;
}
}
public void setStop(boolean stop){
this.isStop = stop;
}
}
那麼就可以在外面通過調用setStop方法來終止while循環。
5.Thread其他方法:
1)getId 用來得到線程ID。
2)getName和setName。用來得到或者設置線程名稱。
3)getPriority和setPriority。用來獲取和設置線程優先級。
4)setDaemon和isDaemon。用來設置線程是否成爲守護線程和判斷線程是否是守護線程。
5)currentThread()。常用,用來獲取當前線程。
演示關係圖如下: