1. 程式人生 > >執行緒阻塞和中斷(sleep、wait、io、鎖)四種恢復方式

執行緒阻塞和中斷(sleep、wait、io、鎖)四種恢復方式

1、執行緒阻塞 一個執行緒進入阻塞狀態可能的原因: ①通過呼叫sleep(millseconds)使任務進入休眠狀態class Demo1 implements Runnable throws InterruptedException{      public void run(){            Thread.sleep(1000);      } } ②通過呼叫wait()使執行緒掛起,直到執行緒獲取notify()/notifyAll()訊息,(或者在Java SE5中java.util.concurrent類庫中等價的signal()/signalAll()訊息),執行緒才會進入就緒狀態; class Demo2 implements Runnable{
     public void run(){           Thread.await();           Thread.notify();      } } ③任務在等待某個輸入 / 輸出流的完成; class Demo3 implements Runnable throws InterruptedException{      private InputStream in;      public void run(){           in.read();      } } ④任務試圖在某個物件上呼叫其同步控制方法,但是物件鎖不可用,因為另一個任務已經獲取了該鎖; class Demo4 implements Runnable{      public synchronized void method1(){     }      public synchronized void method2(){     }      public void run(){           method1();
     } } 2、執行緒中斷的方法 Thread類包含interrupt()方法,用於終止阻塞任務; 1)中斷①②類執行緒休眠,掛起阻塞的方法 1.直接使用Thread.interrupt(); main(){      Thread t = new Thread(new Demo1());      t.interrupt(); } 2.使用Executor執行緒池,中斷執行緒池中的所有執行緒; main(){      ExecutorService exec = Executors.newCachedThreadPool();      for(int i=0;i<5;i++)
          exec.execute(new Demo1())   exec.shutdownNow(); } 3.使用Executor執行緒池,中斷執行緒池中單個阻塞的執行緒; main(){      ExecutorService exec = Executors.newCachedThreadPool();      Futrue<?> f = exec.submit(new Demo1());      f.interrupt(); } //中斷後的清除程式碼放置在InterruptedException異常的catch捕獲的程式碼塊中 2)中斷③類I/O阻塞的方法 使用Thread.iterrupt方法無法中斷I/O阻塞,這對於基於Web的程式是很不利的; ①有一種解決方法:關閉任務在其上發生阻塞的底層資源; main(){      ExecutorService exec = Executors.newCachedThreadPool();      ServerSocket server = new ServerSocket(8080);      InputStream socketInput = new Socket("localhost",8080)      exec.execute(socketInput);      exec.execute(Sytsem.in);      //exec.shutdownNow(); 無法中斷2個執行緒;      socketInput.close();      in.close();      exec.shutdownNow(); } ②java.nio類庫提供了更加人性化的I/O中斷,被阻塞的nio通道會自動地響應中斷; class Demo impelenets Runnable{      private final SocketChannel sc;      public Demo(SocketChannel sc){ this.sc = sc;}      public void run(){           try{                sc.read(ByteBuffer.allocate(1));           }catch(CloseByInteruptedException e1){           }catch(AsyncronousCloseException e2){           }catch(IOException e3){           }      } } public Test {      public static void main(){           ExecutorService exec = Executors.newCachedThreadPool();           ServerSocket server = new ServerSocket(8080);           InetSocketAddress isa = new InetSocketAddress("localhost",8080);           SocketChannel sc1 = new SocketChannel.open(isa);           SocketChannel sc2 = new SocketChannel.open(isa);           exec.execute(new Demo(sc1));           Future<?> f = exec.submit(new Demo(sc2));           f.cancel(true);  //可以終止sc1通道所在的執行緒;           exec.shutdownNow();  //可以終止exec執行緒池內所有的執行緒;           sc1.close();           sc2.close();      } } 3)中斷④類被互斥阻塞的執行緒 使用Thread.iterrupt方法無法中斷互斥類執行緒, 解決方式1可以使用ReentrantLock顯式加鎖,在JavaSE5中引入的新特性,ReentrantLock上阻塞的任務可以被中斷; class Task imlements Runnable{      private Lock lock = new ReentrantLock();      public void run(){           lock.lock();           try{                while(true)           }catch(InterruptedExcpetion e){                System.out.println("The Task is interrupted!");           }finally{                lock.unlock();           }      }      public void main(){           Thread t = new Thread(new Task());           t.start();           t.interrupt();      } } 解決方式2:使用一個while(!Thread.interrupted())包裹同步的程式碼塊 class Task impelments Runnable{      private synchronized void method1(){     }      public void run(){           try{                whlie(!Thread.interrupted())                     method1();            }catch(InteruptedException e){              }                   }      public static void main(){           ExecutorService exec = Executors.newCachedThreadPool();           exec.execute(new Task());           exec.shutdownNow();  //執行緒被打斷           /*或 Thread t = new Thread(new Task());                t.start();                t.interrupt(); */      } }