Java學習(28)—(執行緒的控制/生命週期/解決安全問題)

姜白告發表於2018-08-07

執行緒的控制

休眠執行緒

public class	ThreadSleep	extends	Thread {
@Override publicvoid run() {
for	(  int	x = 0; x < 100; x++) {
System.	out .println(getName()	+ ":"	+ x + ", 日 期 : "	+ newDate());
//	睡眠
//	困了,我稍微休息	1 秒鐘try		{
Thread.	sleep	(1000);
}	catch	(InterruptedException e)
 { e.printStackTrace();
    }
   }
  }
}

加入執行緒

publicclass	ThreadJoin	extends	Thread {
@Override publicvoid	run() {
for	(  int	x = 0; x < 100; x++) {
System.	out .println(getName() +	":"	+ x);
    }
  }
}
ThreadJoin tj1 = new ThreadJoin(); 
ThreadJoin tj2 = new ThreadJoin(); 
ThreadJoin tj3 = new ThreadJoin();

tj1.setName(" 李淵 " );
tj2.setName(" 李世民 " );
tj3.setName(" 李元霸 " );

tj1.start(); try	{

//	李淵執行完,再執行其他兩個
tj1.join();
}	catch	(InterruptedException e) { e.printStackTrace();
}

tj2.start();
tj3.start();

禮讓執行緒

publicclass	ThreadYield	extends	Thread {
@Override publicvoid	run() {
for	(int x = 0; x < 100; x++) {
System.	out .println(getName() +	":"	+ x);
//	讓其他執行緒先走
Thread.	yield	();
    }
  }
}

後臺執行緒

ThreadDaemon td1 =	new ThreadDaemon(); 
ThreadDaemon td2 =	new ThreadDaemon();

td1.setName(" 關羽 " );
td2.setName(" 張飛 " );

//	設定守護執行緒,主執行緒結束後,守護執行緒也會結束
td1.setDaemon(true); td2.setDaemon(true);

td1.start();
td2.start();
//	設 置 主 線 程 名 為 “ 劉 備 ” 
Thread.currentThread().setName(" 劉備 " ); 
for	( int	x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName() +	":"	+ x);
}

終止執行緒 

public class ThreadStop	extends	Thread {
@Override
public void run() {
   System. out.println(" 開始執行: " +new Date());
   //	我要休息 10 秒鐘,親,不要打擾我哦
   try	{
   Thread.sleep(10000);
   }catch(Interrupted Exception e) {
    // e.printStackTrace();
   System.out.println( " 執行緒被終止了" );
   }
   System.  out .println(" 結束執行: " +new Date());
   }
 }
 ThreadStop ts =new ThreadStop(); 
 ts.start();
//	你超過三秒不醒過來,我就乾死你
try	{ Thread.sleep(3000);
// ts.stop(); ts.interrupt();
}	catch	(InterruptedException e)
 { 
    e.printStackTrace();
 }

執行緒的生命週期

 

多執行緒安全問題

判斷一個程式是否有執行緒安全問題的依據 )

A:是否有多執行緒環境

B:是否有共享資料        

C:是否有多條語句操作共享資料

同步解決執行緒安全問題

同步程式碼塊

synchronized( 物件 ) {
需要被同步的程式碼	;
}
這裡的鎖物件可以是任意物件。
synchronized(d) { if(tickets > 0) {

try	{ Thread.sleep(100);
}	catch	(InterruptedException e) { e.printStackTrace();
  }
System.out.println(Thread.currentThread().getName()
+	" 正在出售第 "  + (tickets--) +	" 張 票 " );
  }
}

同步方法

把同步加在方法上。這裡的鎖物件是	this

privatesynchronizedvoid	sellTicket() { if(tickets > 0) {
try	{
Thread.sleep(100);
}	catch(InterruptedException e) 
{ e.printStackTrace();
  }
System.out.println(Thread.currentThread().getName()
+" 正在出售第 "  + (tickets--) +	" 張 票 " );
  }
}

靜態同步方法

把同步加在方法上。
這裡的鎖物件是當前類的位元組碼檔案物件(反射再講位元組碼檔案物件) private static synchronized void	sellTicket() {
if	(tickets > 0) { 
try	{
Thread.sleep(100);
}	
catch(InterruptedException e){ 
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+  " 正在出售第 "  + (tickets--) +" 張票 " );
    }
}

同步鎖物件

// 定義票
private int tickets = 100;
//	定義鎖物件
private Lock lock =new ReentrantLock();
@Override 
public void run() {
while (true) {
try{
//	加鎖
lock.lock();
if	(tickets > 0) { 
    try	{
        Thread.sleep(100);
    }	
    catch(InterruptedException e) { 
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()
    + " 正在出售第 " + (tickets--) +" 張票 " );
    }
}finally{
//	釋放鎖
    lock.unlock();
    }
  }
}


同步的好處

    同步的出現解決了多執行緒的安全問題。

同步的弊端

    當執行緒相當多時,因為每個執行緒都會去判斷同步上的鎖,這是很耗費資源的, 無形中會降低程式的執行效率。


相關文章