1.定義類別繼承Thread類,覆寫類別中的run方法,呼叫類別物件的start方法,start方法啟動線程,呼叫run方法。 Thread類別用於描述執行緒;該類別定義一個功能run,用於儲存執行緒要執行的程式碼。
2.定義類別實作Runnable接口,覆蓋Runnable接口中的方法,透過Thread類別建立線程對象,將Runnable接口的子類對像作為實際參數傳遞給Thread類的構造函數,調用Thread類的start方法開啟線程,線程會呼叫Runnable介面子類別中的run方法;
實作介面Runnable的方式避免了單一繼承帶來的限制;
Thread T;
T.setMaemon(true);//設定執行緒為後台執行緒;當所有前台執行緒結束後後台執行緒自動結束時;
T.notify();//喚醒本題;
T.notifyAll();//喚醒全部執行緒;
T.interrupt();//中斷執行緒;
Thread.sleep(100);//暫停執行緒100毫秒
synchronized:預設鎖定的是本身,也可以鎖定自訂的物件;
必須要有兩個以上的執行緒執行,多個執行緒使用同一個鎖,必須確保同步過程中只能有一個執行緒在運作;
判斷同步:明確哪些程式碼是需要多執行緒運行的程式碼,明確共享數據,明確多執行緒運行程式碼中哪些語句是操作共享數據;
class Tickets implements Runnable
{
private int tick = 100;
public void run() { // public synchronized void run()
while (tick > 0) {
synchronized (this) {
if (tick > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.toString() + "sale:" + tick--);
}
}
}
}
如上:tick就是共享數據,操作tick就需要在synchronized中進行操作,synchroized鎖定的就是Tickets本身;
等待喚醒機制:在操作同步線程時,都必須要標識它們所操作線程所持有的鎖,只有同一個鎖上的被等待線程,才可以被同一個鎖上的notify喚醒,不可以對不同鎖中的執行緒進行了喚醒;(也即:等待和喚醒必須是同一個鎖定)