線程控制
使目前正在執行的線程停留(暫停)指定的秒數
static void sleep(long millis)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
等待這個線程死亡
void join()
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
t3.start();
設定守護線程,将此線程标記為守護線程,當運作守護線程時,Java虛拟機
void setDaemon(boolean on)
Thread.currentThread().setName("主線程");
//設定守護線程,将此線程标記為守護線程,當運作守護線程時,Java虛拟機
// void setDaemon(boolean on){}
t1.setDaemon(true);
t2.setDaemon(true);
t1.start();
t2.start();
線程生命周期
- 建立(建立線程對象)
- 就緒(有執行資格,沒有執行權)
- 搶到CPU執行權
- 運作(有執行資格,有執行權)
- run方法結束,或者stop()
- 死亡(線程死亡,變成垃圾)
- 阻塞(沒有執行資格,沒有執行權):運作時被sleep或者其他方法阻塞。阻塞結束,回到就緒。
多線程的實作方式2
實作Runnable接口
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
// Thread t1 = new Thread(mr);
// Thread t2 = new Thread(mr);
Thread t1 = new Thread(mr,"張三");
Thread t2 = new Thread(mr,"李四");
t1.start();
t2.start();
}
可以繼承Thread類實作多線程,也可以實作Runnable接口實作多線程。
相比第一種方法,實作Runnable接口能夠:
- 避免了Java單繼承局限性。
- 适合多個相同程式的代碼去處理同一個資源的情況,将線程、程式代碼、資料有效分離,展現了面向對象的設計思想。
線程同步
同步代碼塊:相當于把代碼鎖了,任意對象就可以看出一把鎖。
synchronized (任意對象){
}
- 好處:解決了多線程資料安全問題
- 弊端:線程多時,每個線程都會去判斷同步上的鎖,很消耗資源,降低運作效率。
同步方法
- 把synchronized關鍵字加到方法上
- 格式:修飾符 synchronized 傳回值類型 方法名(){ }
- 同步方法的鎖對象時this。
同步靜态方法
- 将鎖加在靜态方法上,
- 格式:修飾符 static synchronized 傳回值類型 方法名(){ }
- 同步靜态方法的鎖對象時synchronized (SellTicket.class)