Demo1
/* Runable接口比直接從Thread繼承友善的多 。
* new Thread(...) ;這樣即使我們傳遞了同一個實作了Runnable接口的多個對象那麼 也是多個線程 ,而且多個線程共享資料域.
* 否則new Thread 建立的多個線程之間 互不相幹 ,資料之間互不幹涉
* 同步就是為了實作 在多個線程同時對一個資源進行操作的時候 要一個一個的執行 ,
* 隻有等占有CPU的 線程完事之後 其他等待線程才能進入就緒狀态等待運作
* java中可以用 synchrozined(Object obj){} 實作代碼塊的同步 參數是任意對象
* 不但可以利用synchronized語句塊 也可以在方法的前面 聲明 synchronized
* 同步原理是對象的标志位 初始為1 當進入代碼塊後 obj的标志位變為 0 這時候其他線程則不能 進入代碼塊執行 而進入等待狀态
* 直到先進入的那個線程完事然後就會為這個線程解鎖 。 其他線程才可能開始運作 火車票的售票系統就是一個多線程很好的運用的例子
* 同步是以程式的性能為代價的 ,同步方法是以類的this對象為同步對象的 而 synchronized塊是以我們指定的對象為 同步對象
* 如果想讓代碼塊和同步方法同步那麼 使用的同步對象 必須都為this
*/
public class ThreadDemo2
{
public static void main(String []args)
{
MyThread mt=new MyThread() ;
//mt.start() ;
new Thread(mt) .start() ;
try
{
Thread.sleep(10) ; //每當産生一個線程CPU不會立馬去執行 ,這之間既有一個微小的時間間隔 。
}
catch(Exception e)
System.out.println(e.toString()) ;
mt.str="method";
}
}
class MyThread implements Runnable// extends Thread
{
int tickets=100 ;
String str=new String("");
public void run()
if(str.equals("method"))
{
while(true)
{
running() ;
}
}
else
synchronized(str)
if(tickets>0 )
{
System.out.println("block:"+Thread.currentThread().getName()+"sells"+tickets--);
}
public synchronized void running()
{
if(tickets>0)
{
try{Thread.sleep(10);}catch(Exception ex){}
System.out.print("method:") ;
System.out.println(Thread.currentThread() +"sell " + tickets-- ) ;
}
}
Demo2:
/*
* java多線程中 有前台線程和背景線程,前台線程 是指 main所在的主線程 和其他 建立的線程 ,如果線上程調用start 之前調用 setDeamon(true)
* 那麼 這個線程就是一個背景線程,在程序中如果沒有一個前台線程 那麼背景線程也随之退出,進而程序也退出 。如果沒有調用setDeamon(true)或者
* 調用setDeamom(false)那麼這個線程就是前台線程 ,隻要一個程序中還存在前台線程 那麼即使mian方法所在的線程退出了 ,那麼這個前台子線程也會繼續執行
* 直至退出 。
* Tread類額join方法 是将一個線程合并到另一個線程中, 可以設定合并的時間間隔
* 我們實作自己的線程類有2中方法 :
* 1、直接從Thread繼承而來 實作 run方法 。
* 2、實作Runnable接口,并且實作run方法 。 Thread th=new Thread(....) ;//吧我們自己實作的類的對象作為參數傳進去 .
* join 方法可以将一個線程合并到另一個線程 中 而且還可以指定線程合并的時間間隔
*
*/
public class ThreadDemo1
public static void main(String[]args)
{
//MyThread tt=new MyThread() ; tt.start() ;可以從 Thread類派生一個線程類
Thread tt=new Thread(new MyThread()) ; //可以通過Thread類的帶參數的構造方法 傳遞一個實作了Runnable接口的對象
// tt.setDaemon(true) ;//将線程設定為 背景線程 主線層退出這個線程也會随着退出
tt.start() ;
int index=0 ;
while(true)
{
if(index++==100)
try{
tt.join(5000) ;
}
catch(Exception ex)
System.out.println(ex.toString()) ;
}
System.out.println("run:"+Thread.currentThread().getName()) ;
}
class MyThread implements Runnable//extends Thread
public void run()
{
while(true)
System.out.println("run:"+Thread.currentThread().getName()) ;
}
Demo3:
/* 線程之間的通信是協調線程同步的重要方法 、
* Object類的 wait方法通告同步對象進入等待狀态,直到其他線程得到同步對象 并且調用 notity方法 ,等待線程才會繼續執行
* notify方法 是通告同步對象的等待線程進入恢複運作
* notifyAll通告所有堵塞線程恢複運作
* 下面是一個生産消費者的問題 ,在對于類的操作的時候 一定要有面向對象的思想 。 否則 就會非常的雜亂
class Producer implements Runnable
Q q ;
public Producer(Q q)
{
this.q=q ;
}
public void run()
{
int i=0 ;
while(true)
/* synchronized(q)
{
if(q.bFull==true)
try{q.wait() ;}catch(Exception ex){}
if(i==0)
q.name="zhangsan" ;
try{
Thread.sleep(1) ;
}catch(Exception ex){}
q.sex="male" ;
}
else
q.name="lisi" ;
q.sex="female" ;
}
q.bFull=true ;
q.notify() ;
i=(i+1)%2 ;
*/
if(i==0 )
q.push("zhangsan","male");
else
q.push("lisi","female") ;
i=(i+1)%2 ;
class Consumer implements Runnable
Q q ;
public Consumer(Q q)
this.q=q ;
public void run()
while(true)
{
/* synchronized(q)
{
if(!q.bFull)
{
try{q.wait() ;}catch(Exception ex){}
}
System.out.println(q.name+":"+q.sex) ;
q.bFull=false ;
q.notify() ;
}
*/
q.get() ;
}
class Q //以面向對象的思想對線程之間的通信進行封裝進而實作消費者 生産社的問題
String name="unknown" ;
String sex ="unknown" ;
boolean bFull=false ;
public synchronized void push(String name,String sex)
{
if(this.bFull==true)
try{wait() ;}catch(Exception ex){}
this.name=name ;
this.sex=sex ;
bFull=true ;
try{notify() ;}catch(Exception ex){}
public synchronized void get()
if(this.bFull==false)
try{wait() ;}catch(Exception ex){}
System.out.println("name:"+this.name+" sex:"+this.sex) ;
bFull=false ;
try{notify() ;}catch(Exception ex){}
class ThreadTest implements Runnable //這個線程類 來模拟線程的聲明結束 因為Thread類的 stop suspend等方法都已經過時了
{ //是以有時候我們對于線程的開始和結束要自己設定标志位來
boolean bRun=true ;
int index=0 ;
public void stopMe()
{
bRun=false ;
}
public void run()
while(bRun)
{
if(++index>100)
stopMe() ;
System.out.println(Thread.currentThread().getName()+" is running!");
}
public class ThreadDemo3
public static void main(String[]args)
Q q=new Q() ;
new Thread(new Producer(q)).start() ;
new Thread(new Consumer(q)).start() ;