java程序設計--孫鑫java無難事Lesson7《多線程》

java程序設計--孫鑫java無難事Lesson7《多線程》
1.程序、進程和線程
程序:   程序是計算機指令的集合,它以文件的形式存儲在磁盤上。
進程:是一個程序在其自身的地址空間中的一次執行活動。
進程是資源申請、調度和獨立運行的單位,因此,它使用系統中的運行資源;而程序不能申請系統資源,不能被系統調度,也不能作爲獨立運行的單位,因此,它不佔用系統的運行資源。

線程:是進程中的一個單一的連續控制流程。一個進程可以擁有多個線程。線程又稱爲輕量級進程,它和進程一樣擁有獨立的執行控制,由操作系統負責調度,區別在於線程沒有獨立的存儲空間,而是和所屬進程中的其它線程共享一個存儲空間,這使得線程間的通信遠較進程簡單。

2.java多線程實現
Java在語言級提供了對多線程程序設計的支持。
實現多線程程序的兩種方式:
a.從Thread類繼承
b.實現Runnable接口
(1)實現方式1從Thread類繼承
測試代碼如下:
  1. class MyThread extends Thread  
  2. {     
  3.     MyThread(String name)  
  4.     {  
  5.        super(name);  
  6.     }  
  7.     public void run()  
  8.     {     
  9.         while(true)  
  10.         {  
  11.             System.out.println(getName());  
  12.             yield();//暫停線程運行   
  13.         }  
  14.     }  
  15. }  
  16. class MultiThread  
  17. {  
  18.     public static void main(String[] args)  
  19.     {     
  20.           
  21.         //從Thread類派生   
  22.         MyThread mt=new MyThread("Thread1");  
  23.         //mt.setDaemon(true);//標記爲後臺線程   
  24.         mt.setPriority(Thread.MAX_PRIORITY );//設置最高優先級   
  25.         mt.start();//啓動線程   
  26.         int index=0;  
  27.         //當僅有後臺線程運行時java虛擬機將退出   
  28.         while(true)  
  29.         {     
  30.             if(index++ == 100)  
  31.                 break;//main方法退出   
  32.             System.out.println("main:"+Thread.currentThread().getName());  
  33.         }  
  34. }  
class MyThread extends Thread
{   
    MyThread(String name)
    {
       super(name);
    }
    public void run()
    {   
        while(true)
        {
            System.out.println(getName());
            yield();//暫停線程運行
        }
    }
}
class MultiThread
{
    public static void main(String[] args)
    {   
        
        //從Thread類派生
        MyThread mt=new MyThread("Thread1");
        //mt.setDaemon(true);//標記爲後臺線程
        mt.setPriority(Thread.MAX_PRIORITY );//設置最高優先級
        mt.start();//啓動線程
        int index=0;
        //當僅有後臺線程運行時java虛擬機將退出
        while(true)
        {   
            if(index++ == 100)
                break;//main方法退出
            System.out.println("main:"+Thread.currentThread().getName());
        }
}
(2)實現方式2實現Runnable接口
測試代碼如下:
//實現接口  允許繼承類並且實現接口     同一資源的訪問
  1. class MyThread implements Runnable  
  2. {     
  3.     int index=0;//共享變量   
  4.     public void run()  
  5.     {     
  6.         while(true)  
  7.         {  
  8.             System.out.println(Thread.currentThread().getName()+index++);  
  9.         }  
  10.     }  
  11. }  
  12. class MultiThread  
  13. {  
  14.     public static void main(String[] args)  
  15.     {    
  16.         MyThread mt=new MyThread( );  
  17.         new Thread(mt).start();//傳遞Runnable接口的實現類對象   
  18.         new Thread(mt).start();  
  19.         new Thread(mt).start();  
  20.         new Thread(mt).start();  
  21.         while(true)  
  22.         {     
  23.             System.out.println("main:"+Thread.currentThread().getName());  
  24.         }  
  25. }  
class MyThread implements Runnable
{   
    int index=0;//共享變量
    public void run()
    {   
        while(true)
        {
            System.out.println(Thread.currentThread().getName()+index++);
        }
    }
}
class MultiThread
{
    public static void main(String[] args)
    {  
        MyThread mt=new MyThread( );
        new Thread(mt).start();//傳遞Runnable接口的實現類對象
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
        while(true)
        {   
            System.out.println("main:"+Thread.currentThread().getName());
        }
}

運行過程中如下圖所示:


(3)實現方式3利用內部類從Thread類繼承
測試代碼如下:
  1. //利用內部類繼承Thread   
  2. class MyThread  
  3. {     
  4.     int index=0;  
  5.     private class InnerThread extends Thread  
  6.     {  
  7.         public void run()  
  8.         {     
  9.             while(true)  
  10.             {  
  11.                 System.out.println    (Thread.currentThread().getName()+index++);  
  12.             }  
  13.         }  
  14.     }  
  15.     public  Thread getThread()  
  16.     {  
  17.        return new InnerThread();  
  18.     }  
  19. }  
  20. class MultiThread  
  21. {  
  22.     public static void main(String[] args)  
  23.     {  MyThread mt=new MyThread();  
  24.         mt.getThread().start();  
  25.         mt.getThread().start();  
  26.         while(true)  
  27.         {     
  28.             System.out.println("main:"+Thread.currentThread().getName());  
  29.         }  
  30.     }  
  31. }  
//利用內部類繼承Thread
class MyThread
{   
    int index=0;
    private class InnerThread extends Thread
    {
        public void run()
        {   
            while(true)
            {
                System.out.println    (Thread.currentThread().getName()+index++);
            }
        }
    }
    public  Thread getThread()
    {
       return new InnerThread();
    }
}
class MultiThread
{
    public static void main(String[] args)
    {  MyThread mt=new MyThread();
        mt.getThread().start();
        mt.getThread().start();
        while(true)
        {   
            System.out.println("main:"+Thread.currentThread().getName());
        }
    }
}
3.線程的同步
同步的兩種方式:同步塊和同步方法
每一個對象都有一個監視器,或者叫做鎖。
同步方法利用的是this所代表的對象的鎖。靜態方法的同步利用的該類的Class對象的監視器。每個class也有一個鎖,是這個class所對應的Class對象的鎖。
(1)線程未同步時出錯:
測試代碼如下:
  1. class SellThread implements Runnable  
  2. {     
  3.     int tickets=1000;  
  4.     Object ob=new Object();  
  5.     public void run()  
  6.     {     
  7.         while(true)  
  8.         {     
  9.             //不加鎖   
  10.             if(tickets>0)  
  11.                 {     
  12.                     try  
  13.                     {  
  14.                         Thread.sleep(5);  
  15.                     }  
  16.                     catch (Exception e)  
  17.                     {  
  18.                         System.out.println(e.toString());  
  19.                     }  
  20.                     System.out.println(Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  21.                     tickets--;  
  22.                 }  
  23. }  
  24. class TicketsSystem  
  25. {  
  26.     public static void main(String[] args)  
  27.     {     
  28.         SellThread st=new SellThread();  
  29.         new Thread(st).start();  
  30.         new Thread(st).start();  
  31.     }  
  32. }  
class SellThread implements Runnable
{   
    int tickets=1000;
    Object ob=new Object();
    public void run()
    {   
        while(true)
        {   
            //不加鎖
            if(tickets>0)
                {   
                    try
                    {
                        Thread.sleep(5);
                    }
                    catch (Exception e)
                    {
                        System.out.println(e.toString());
                    }
                    System.out.println(Thread.currentThread().getName()+" Sell Tickets"+tickets);
                    tickets--;
                }
}
class TicketsSystem
{
    public static void main(String[] args)
    {   
        SellThread st=new SellThread();
        new Thread(st).start();
        new Thread(st).start();
    }
}
//運行結果
Thread-0 Sell Tickets11
Thread-1 Sell Tickets10
Thread-0 Sell Tickets9
Thread-1 Sell Tickets8
Thread-0 Sell Tickets7
Thread-1 Sell Tickets6
Thread-0 Sell Tickets5
Thread-1 Sell Tickets4
Thread-0 Sell Tickets3
Thread-1 Sell Tickets2
Thread-0 Sell Tickets1
Thread-1 Sell Tickets0
(2)線程同步方法1--利用同步塊
測試代碼如下:
  1. class SellThread implements Runnable  
  2. {     
  3.     int tickets=1000;  
  4.     Object ob=new Object();  
  5.     public void run()  
  6.     {     
  7.         while(true)  
  8.         { synchronized(ob)//同步塊   對Object對象加鎖   
  9.             {  
  10.                 if(tickets>0)  
  11.                 {     
  12.                     try  
  13.                     {  
  14.                         Thread.sleep(5);  
  15.                     }  
  16.                     catch (Exception e)  
  17.                     {  
  18.                         System.out.println(e.toString());  
  19.                     }  
  20.                     System.out.println(Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  21.                     tickets--;  
  22.                 }  
  23.             }//同步塊執行完畢 解鎖   
  24. }  
  25. class TicketsSystem  
  26. {  
  27.     public static void main(String[] args)  
  28.     {     
  29.         SellThread st=new SellThread();  
  30.         new Thread(st).start();  
  31.         new Thread(st).start();  
  32.     }  
  33. }  
class SellThread implements Runnable
{   
    int tickets=1000;
    Object ob=new Object();
    public void run()
    {   
        while(true)
        { synchronized(ob)//同步塊   對Object對象加鎖
            {
                if(tickets>0)
                {   
                    try
                    {
                        Thread.sleep(5);
                    }
                    catch (Exception e)
                    {
                        System.out.println(e.toString());
                    }
                    System.out.println(Thread.currentThread().getName()+" Sell Tickets"+tickets);
                    tickets--;
                }
            }//同步塊執行完畢 解鎖
}
class TicketsSystem
{
    public static void main(String[] args)
    {   
        SellThread st=new SellThread();
        new Thread(st).start();
        new Thread(st).start();
    }
}

同步塊,運行結果如下圖所示:


(3)線程同步方法2--同步方法
測試代碼如下:
  1. class SellThread implements Runnable  
  2. {     
  3.     int tickets=1000;  
  4.     Object ob=new Object();  
  5.     public void run()  
  6.     {     
  7.         while(true)  
  8.         {  
  9.             sell();//同步方法   
  10.         }  
  11.     }  
  12. //synchronized關鍵字定義  同步方法  對this對象的監視器加鎖   
  13.     public synchronized void sell()  
  14.     {  
  15.           if(tickets>0)  
  16.                 {     
  17.                     try  
  18.                     {  
  19.                         Thread.sleep(10);  
  20.                     }  
  21.                     catch (Exception e)  
  22.                     {  
  23.                         System.out.println(e.toString());  
  24.                     }  
  25.                     System.out.println(Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  26.                     tickets--;  
  27.                 }  
  28.     }//解鎖this對象   
  29. }  
  30. class TicketsSystem  
  31. {  
  32.     public static void main(String[] args)  
  33.     {     
  34.         SellThread st=new SellThread();  
  35.         new Thread(st).start();  
  36.         new Thread(st).start();  
  37.     }  
  38. }  
class SellThread implements Runnable
{   
    int tickets=1000;
    Object ob=new Object();
    public void run()
    {   
        while(true)
        {
            sell();//同步方法
        }
    }
//synchronized關鍵字定義  同步方法  對this對象的監視器加鎖
    public synchronized void sell()
    {
          if(tickets>0)
                {   
                    try
                    {
                        Thread.sleep(10);
                    }
                    catch (Exception e)
                    {
                        System.out.println(e.toString());
                    }
                    System.out.println(Thread.currentThread().getName()+" Sell Tickets"+tickets);
                    tickets--;
                }
    }//解鎖this對象
}
class TicketsSystem
{
    public static void main(String[] args)
    {   
        SellThread st=new SellThread();
        new Thread(st).start();
        new Thread(st).start();
    }
}

同步方法,運行結果如下圖所示:


(4)注意同步方法中是對this對象加鎖,而同步塊中是對定義的某個Object對象同步。
驗證代碼如下:
  1. class SellThread implements Runnable  
  2. {     
  3.     int tickets=500;//不同的數據可能線程的運行結果不一樣   
  4.     Object obj=new Object();  
  5.     boolean b=false;  
  6.     public void run()  
  7.     {     
  8.         if(b==false)  
  9.         {  
  10.             while(true)  
  11.             {  
  12.                 sell();  
  13.             }  
  14.         }  
  15.         else  
  16.         {  
  17.             while(true)  
  18.             {     
  19.                 synchronized(obj)  //同步obj對象則出錯  同步this則正確   
  20.                 {  
  21.                    try  
  22.                     {  
  23.                         Thread.sleep(10);  
  24.                     }  
  25.                     catch (Exception e)  
  26.                     {  
  27.                         System.out.println(e.toString());  
  28.                     }  
  29.                     if(tickets>0)  
  30.                     {    
  31.                         System.out.println("Obj"+Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  32.                         tickets--;  
  33.                     }  
  34.                 }  
  35.             }  
  36.         }  
  37.     }  
  38.     //同步方法  對this對象的監視器加鎖   
  39.     public synchronized void sell()  
  40.     {     
  41.       if(tickets>0)  
  42.         {     
  43.             try  
  44.             {  
  45.                 Thread.sleep(10);  
  46.             }  
  47.             catch (Exception e)  
  48.             {  
  49.                 System.out.println(e.toString());  
  50.             }  
  51.             System.out.println("Sell"+Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  52.             tickets--;  
  53.         }  
  54.     }//解鎖this對象   
  55. }  
class SellThread implements Runnable
{   
    int tickets=500;//不同的數據可能線程的運行結果不一樣
    Object obj=new Object();
    boolean b=false;
    public void run()
    {   
        if(b==false)
        {
            while(true)
            {
                sell();
            }
        }
        else
        {
            while(true)
            {   
                synchronized(obj)  //同步obj對象則出錯  同步this則正確
                {
                   try
                    {
                        Thread.sleep(10);
                    }
                    catch (Exception e)
                    {
                        System.out.println(e.toString());
                    }
                    if(tickets>0)
                    {  
                        System.out.println("Obj"+Thread.currentThread().getName()+" Sell Tickets"+tickets);
                        tickets--;
                    }
                }
            }
        }
    }
    //同步方法  對this對象的監視器加鎖
    public synchronized void sell()
    {   
      if(tickets>0)
        {   
            try
            {
                Thread.sleep(10);
            }
            catch (Exception e)
            {
                System.out.println(e.toString());
            }
            System.out.println("Sell"+Thread.currentThread().getName()+" Sell Tickets"+tickets);
            tickets--;
        }
    }//解鎖this對象
}

當一個調用sell方法,一個利用Object對象同步時,出錯,錯誤結果如下圖所示:


當一個調用sell方法,另一個利用this對象同步時,結果正確,如下圖所示:


4.線程死鎖
死鎖測試代碼:
  1. //測試死鎖   
  2. class SellThread implements Runnable  
  3. {     
  4.     int tickets=500;  
  5.     Object obj=new Object();  
  6.     boolean b=false;  
  7.     public void run()  
  8.     {     
  9.         if(b)  
  10.         {  
  11.             while(true)  
  12.                 sell();  
  13.         }  
  14.         else  
  15.         {     
  16.             while(true)  
  17.             {     
  18.                 //先同步obj對象 然後同步this對象   
  19.                 synchronized(obj)    
  20.                 {  
  21.                    try  
  22.                     {  
  23.                         Thread.sleep(10);  
  24.                     }  
  25.                     catch (Exception e)  
  26.                     {  
  27.                         System.out.println(e.toString());  
  28.                     }  
  29.                     synchronized(this)     
  30.                     {  
  31.                         if(tickets>0)  
  32.                         {    
  33.                             System.out.println("DeadLock"+Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  34.                             tickets--;  
  35.                         }  
  36.                     }  
  37.                 }  
  38.             }  
  39.         }  
  40.     }  
  41.     //先同步this對象然後再同步obj對象   
  42.     public synchronized void sell()  
  43.     {     
  44.         synchronized(obj)     
  45.         {     
  46.             try  
  47.             {  
  48.                 Thread.sleep(10);  
  49.             }  
  50.             catch (Exception e)  
  51.             {  
  52.                 System.out.println(e.toString());  
  53.             }  
  54.             if(tickets>0)  
  55.             {     
  56.                 System.out.println("DeadLock"+Thread.currentThread().getName()+" Sell Tickets"+tickets);  
  57.                 tickets--;  
  58.             }  
  59.         }  
  60.     }//解鎖this對象   
  61. }  
  62. class TicketsSystem  
  63. {  
  64.     public static void main(String[] args)  
  65.     {     
  66.         SellThread st=new SellThread();  
  67.         new Thread(st).start();  
  68.         try  
  69.         {  
  70.             Thread.sleep(10);  
  71.         }  
  72.         catch (Exception e)  
  73.         {  
  74.             System.out.println(e.toString());  
  75.         }  
  76.         st.b=true;  
  77.         new Thread(st).start();  
  78.     }  
  79. }  
//測試死鎖
class SellThread implements Runnable
{   
    int tickets=500;
    Object obj=new Object();
    boolean b=false;
    public void run()
    {   
        if(b)
        {
            while(true)
                sell();
        }
        else
        {   
            while(true)
            {   
                //先同步obj對象 然後同步this對象
                synchronized(obj)  
                {
                   try
                    {
                        Thread.sleep(10);
                    }
                    catch (Exception e)
                    {
                        System.out.println(e.toString());
                    }
                    synchronized(this)   
                    {
                        if(tickets>0)
                        {  
                            System.out.println("DeadLock"+Thread.currentThread().getName()+" Sell Tickets"+tickets);
                            tickets--;
                        }
                    }
                }
            }
        }
    }
    //先同步this對象然後再同步obj對象
    public synchronized void sell()
    {   
        synchronized(obj)   
        {   
            try
            {
                Thread.sleep(10);
            }
            catch (Exception e)
            {
                System.out.println(e.toString());
            }
            if(tickets>0)
            {   
                System.out.println("DeadLock"+Thread.currentThread().getName()+" Sell Tickets"+tickets);
                tickets--;
            }
        }
    }//解鎖this對象
}
class TicketsSystem
{
    public static void main(String[] args)
    {   
        SellThread st=new SellThread();
        new Thread(st).start();
        try
        {
            Thread.sleep(10);
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
        }
        st.b=true;
        new Thread(st).start();
    }
}
//運行結果如下:
DeadLockThread-0 Sell Tickets500
5.wait、notify、notifyAll
每一個對象除了有一個鎖之外,還有一個等待隊列(wait set),當一個對象剛創建的時候,它的等待隊列是空的。

我們應該在當前線程鎖住對象的鎖後,去調用該對象的wait方法。

當調用對象的notify方法時,將從該對象的等待隊列中刪除一個任意選擇的線程,這個線程將再次成爲可運行的線程。當調用對象的notifyAll方法時,將從該對象的等待隊列中刪除所有等待的線程,這些線程將成爲可運行的線程。

wait和notify主要用於producer-consumer這種關係中。
(1)notify和wait方法需要在同步塊中執行否則出錯,錯誤信息如下:
Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalM
onitorStateException
        at java.lang.Object.notify(Native Method)
        at Queue.get(Test.java:81)
        at Consumer.run(Test.java:40)
java.lang.IllegalMonitorStateException
        at java.lang.Object.notify(Native Method)
        at Queue.put(Test.java:55)
        at Producer.run(Test.java:23)
同時注意wait方法需要捕獲異常。
(2)消費者和生成者同步的模擬
測試代碼如下:
  1. class Test  
  2. {  
  3.     public static void main(String[] args)  
  4.     {     
  5.         Queue q=new Queue();  
  6.         Producer p=new Producer(q);  
  7.         Consumer c=new Consumer(q);  
  8.         p.start();  
  9.         c.start();  
  10.     }  
  11. }  
  12. class Producer extends Thread  
  13. {     
  14.     Queue q;  
  15.     Producer(Queue q)  
  16.     {  
  17.        this.q=q;  
  18.     }  
  19.     public void run()  
  20.     {  
  21.        for(int i=0;i<10;i++)  
  22.         {  
  23.            q.put(i);  
  24.            System.out.println("Producer put "+i);  
  25.         }  
  26.     }  
  27. }  
  28. class  Consumer extends Thread  
  29. {  
  30.     Queue q;  
  31.     Consumer(Queue q)  
  32.     {  
  33.        this.q=q;  
  34.     }  
  35.     public void run()  
  36.     {     
  37.         while(true)  
  38.         {     
  39.             System.out.println("Consumer get "+q.get());  
  40.         }  
  41.     }  
  42. }  
  43. class Queue  
  44. {  
  45.     int value=-1;  
  46.     boolean bfull=false;  
  47.     //注意同步塊 wait和notify時必須對於同一個對象的隊列   
  48.     public synchronized void put(int i)  
  49.     {    
  50.         //爲空則放置數據   
  51.         if(!bfull)  
  52.         {  
  53.             value=i;  
  54.             bfull=true;  
  55.             notify();//通知等待的消費者   
  56.         }  
  57.         try  
  58.         {  
  59.             wait();  
  60.         }  
  61.         catch (Exception e)  
  62.         {  
  63.                 System.out.println(e.toString());  
  64.         }  
  65.     }  
  66.     public synchronized int get()  
  67.     {     
  68.         //爲空則等待填充數據   
  69.         if(!bfull)  
  70.         {  
  71.            try  
  72.            {  
  73.               wait();  
  74.            }  
  75.            catch (Exception e)  
  76.            {  
  77.                 System.out.println(e.toString());  
  78.            }  
  79.         }  
  80.         bfull=false;  
  81.         notify();//通知等待的生產者   
  82.         return value;  
  83.     }  
  84. }  
class Test
{
    public static void main(String[] args)
    {   
        Queue q=new Queue();
        Producer p=new Producer(q);
        Consumer c=new Consumer(q);
        p.start();
        c.start();
    }
}
class Producer extends Thread
{   
    Queue q;
    Producer(Queue q)
    {
       this.q=q;
    }
    public void run()
    {
       for(int i=0;i<10;i++)
        {
           q.put(i);
           System.out.println("Producer put "+i);
        }
    }
}
class  Consumer extends Thread
{
    Queue q;
    Consumer(Queue q)
    {
       this.q=q;
    }
    public void run()
    {   
        while(true)
        {   
            System.out.println("Consumer get "+q.get());
        }
    }
}
class Queue
{
    int value=-1;
    boolean bfull=false;
    //注意同步塊 wait和notify時必須對於同一個對象的隊列
    public synchronized void put(int i)
    {  
        //爲空則放置數據
        if(!bfull)
        {
            value=i;
            bfull=true;
            notify();//通知等待的消費者
        }
        try
        {
            wait();
        }
        catch (Exception e)
        {
                System.out.println(e.toString());
        }
    }
    public synchronized int get()
    {   
        //爲空則等待填充數據
        if(!bfull)
        {
           try
           {
              wait();
           }
           catch (Exception e)
           {
                System.out.println(e.toString());
           }
        }
        bfull=false;
        notify();//通知等待的生產者
        return value;
    }
}
//運行結果(不知道爲什麼不是先打印Producer)
Consumer get 0
Producer put 0
Consumer get 1
Producer put 1
Consumer get 2
Producer put 2
Consumer get 3
Producer put 3
Consumer get 4
Producer put 4
Consumer get 5
Producer put 5
Consumer get 6
Producer put 6
Consumer get 7
Producer put 7
Consumer get 8
Producer put 8
Consumer get 9
Producer put 9
6.線程終止
設置一個flag變量並結合interrupt()方法。
測試代碼如下:
  1. class TestThread  
  2. {  
  3.     public static void main(String[] args)  
  4.     {     
  5.         Thread1 t1=new Thread1();  
  6.         t1.start();  
  7.         int index=0;  
  8.         while(true)  
  9.         {  
  10.            if(index++ == 500)  
  11.             {  
  12.                t1.stopThread();//調用後置停止運行標誌爲true   
  13.                t1.interrupt();//停止運行線程   
  14.                break;  
  15.            }  
  16.            System.out.println(Thread.currentThread().getName());  
  17.         }  
  18.         System.out.println("main exit!");  
  19.     }  
  20. }  
  21. class Thread1 extends Thread  
  22. {  
  23.     private boolean bstop=false;  
  24.     public synchronized void run()  
  25.     {  
  26.         while(!bstop)  
  27.         {     
  28.             try  
  29.             {  
  30.                 wait();//導致無法比較bstop 無法退出   
  31.             }  
  32.             catch (InterruptedException e)  
  33.             {     
  34.                 //結合一個標誌,在interrupt函數執行時判斷標誌,退出程序   
  35.                 if(bstop)  
  36.                     return;  
  37.                 e.printStackTrace();  
  38.             }  
  39.            System.out.println(getName());  
  40.         }  
  41.       
  42.     }  
  43.     public void stopThread()  
  44.     {  
  45.        bstop=true;//置停止運行標誌爲true   
  46.     }  
  47. }  
class TestThread
{
    public static void main(String[] args)
    {   
        Thread1 t1=new Thread1();
        t1.start();
        int index=0;
        while(true)
        {
           if(index++ == 500)
            {
               t1.stopThread();//調用後置停止運行標誌爲true
               t1.interrupt();//停止運行線程
               break;
           }
           System.out.println(Thread.currentThread().getName());
        }
        System.out.println("main exit!");
    }
}
class Thread1 extends Thread
{
    private boolean bstop=false;
    public synchronized void run()
    {
        while(!bstop)
        {   
            try
            {
                wait();//導致無法比較bstop 無法退出
            }
            catch (InterruptedException e)
            {   
                //結合一個標誌,在interrupt函數執行時判斷標誌,退出程序
                if(bstop)
                    return;
                e.printStackTrace();
            }
           System.out.println(getName());
        }
    
    }
    public void stopThread()
    {
       bstop=true;//置停止運行標誌爲true
    }
}
//運行結果如下
main
main
main
main
main
main
main
main
main
main exit!
請按任意鍵繼續. . .
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章