亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

為何會堵塞

2019-11-18 13:23:06
字體:
來源:轉載
供稿:網友

  堵塞狀態是前述四種狀態中最有趣的,值得我們作進一步的探討。線程被堵塞可能是由下述五方面的原因造成的:
  (1) 調用sleep(毫秒數),使線程進入“睡眠”狀態。在規定的時間內,這個線程是不會運行的。
  (2) 用suspend()暫停了線程的執行。除非線程收到resume()消息,否則不會返回“可運行”狀態。
  (3) 用wait()暫停了線程的執行。除非線程收到nofify()或者notifyAll()消息,否則不會變成“可運行”(是的,這看起來同原因2非常相象,但有一個明顯的區別是我們馬上要揭示的)。
  (4) 線程正在等候一些IO(輸入輸出)操作完成。
  (5) 線程試圖調用另一個對象的“同步”方法,但那個對象處于鎖定狀態,暫時無法使用。
  亦可調用yield()(Thread類的一個方法)自動放棄CPU,以便其他線程能夠運行。然而,假如調度機制覺得我們的線程已擁有足夠的時間,并跳轉到另一個線程,就會發生同樣的事情。也就是說,沒有什么能防止調度機制重新啟動我們的線程。線程被堵塞后,便有一些原因造成它不能繼續運行。
  下面這個例子展示了進入堵塞狀態的全部五種途徑。它們全都存在于名為Blocking.java的一個文件中,但在這兒采用散落的片斷進行解釋(大家可注重到片斷前后的“Continued”以及“Continuing”標志。利用第17章介紹的工具,可將這些片斷連結到一起)。首先讓我們看看基本的框架:
  //: Blocking.java
  // Demonstrates the various ways a thread
  // can be blocked.
  import java.awt.*;
  import java.awt.event.*;
  import java.applet.*;
  import java.io.*;
  //////////// The basic framework ///////////
  class Blockable extends Thread {
   PRivate Peeker peeker;
   protected TextField state = new TextField(40);
   protected int i;
   public Blockable(Container c) {
   c.add(state);
   peeker = new Peeker(this, c);
   }
   public synchronized int read() { return i; }
   protected synchronized void update() {
   state.setText(getClass().getName()
   + " state: i = " + i);
   }
   public void stopPeeker() {
   // peeker.stop(); Deprecated in Java 1.2
   peeker.terminate(); // The preferred approach
   }
  }
  class Peeker extends Thread {
   private Blockable b;
   private int session;
   private TextField status = new TextField(40);
   private boolean stop = false;
   public Peeker(Blockable b, Container c) {
   c.add(status);
   this.b = b;
   start();
   }
   public void terminate() { stop = true; }
   public void run() {
   while (!stop) {
   status.setText(b.getClass().getName()
   + " Peeker " + (++session)
   + "; value = " + b.read());
   try {
   sleep(100);
   } catch (InterruptedException e){}
   }
   }
  } ///:Continued
  Blockable類打算成為本例所有類的一個基礎類。一個Blockable對象包含了一個名為state的TextField(文本字段),用于顯示出對象有關的信息。用于顯示這些信息的方法叫作update()。我們發現它用getClass.getName()來產生類名,而不是僅僅把它打印出來;這是由于update(0不知道自己為其調用的那個類的準確名字,因為那個類是從Blockable衍生出來的。
  在Blockable中,變動指示符是一個int i;衍生類的run()方法會為其增值。
  針對每個Bloackable對象,都會啟動Peeker類的一個線程。Peeker的任務是調用read()方法,檢查與自己關聯的Blockable對象,看看i是否發生了變化,最后用它的status文本字段報告檢查結果。注重read()和update()都是同步的,要求對象的鎖定能自由解除,這一點非常重要。
  1. 睡眠
  這個程序的第一項測試是用sleep()作出的:
  ///:Continuing
  ///////////// Blocking via sleep() ///////////
  class Sleeper1 extends Blockable {
   public Sleeper1(Container c) { super(c); }
   public synchronized void run() {
   while(true) {
   i++;
   update();
   try {
   sleep(1000);
   } catch (InterruptedException e){}
   }
   }
  }
  class Sleeper2 extends Blockable {
   public Sleeper2(Container c) { super(c); }
   public void run() {
   while(true) {
   change();
   try {
   sleep(1000);
   } catch (InterruptedException e){}
   }
   }
   public synchronized void change() {
   i++;
   update();
   }
  } ///:Continued
  在Sleeper1中,整個run()方法都是同步的。我們可看到與這個對象關聯在一起的Peeker可以正常運行,直到我們啟動線程為止,隨后Peeker便會完全停止。這正是“堵塞”的一種形式:因為Sleeper1.run()是同步的,而且一旦線程啟動,它就肯定在run()內部,方法永遠不會放棄對象鎖定,造成Peeker線程的堵塞。
  Sleeper2通過設置不同步的運行,提供了一種解決方案。只有change()方法才是同步的,所以盡管run()位于sleep()內部,Peeker仍然能訪問自己需要的同步方法——read()。在這里,我們可看到在啟動了Sleeper2線程以后,Peeker會持續運行下去。
  2. 暫停和恢復
  這個例子接下來的一部分引入了“掛起”或者“暫?!保⊿uspend)的概述。Thread類提供了一個名為suspend()的方法,可臨時中止線程;以及一個名為resume()的方法,用于從暫停處開始恢復線程的執行。顯然,我們可以推斷出resume()是由暫停線程外部的某個線程調用的。在這種情況下,需要用到一個名為Resumer(恢復器)的獨立類。演示暫停/恢復過程的每個類都有一個相關的恢復器。如下所示:
  ///:Continuing
  /////////// Blocking via suspend() ///////////
  class SuspendResume extends Blockable {
   public SuspendResume(Container c) {
   super(c);
   new Resumer(this);
   }
  }
  class SuspendResume1 extends SuspendResume {
   public SuspendResume1(Container c) { super(c);}
   public synchronized void run() {
   while(true) {
   i++;
   update();
   suspend(); // Deprecated in Java 1.2
   }
   }
  }
  class SuspendResume2 extends SuspendResume {
   public SuspendResume2(Container c) { super(c);}
   public void run() {
   while(true) {
   change();
   suspend(); // Deprecated in Java 1.2
   }
   }
   public synchronized void change() {
   i++;
   update();
   }
  }
  class Resumer extends Thread {
   private SuspendResume sr;
   public Resumer(SuspendResume sr) {
   this.sr = sr;
   start();
   }
   public void run() {
   while(true) {
   try {
   sleep(1000);
   } catch (InterruptedException e){}
   sr.resume(); // Deprecated in Java 1.2
   }
   }
  } ///:Continued
  SuspendResume1也提供了一個同步的run()方法。同樣地,當我們啟動這個線程以后,就會發現與它關聯的Peeker進入“堵塞”狀態,等候對象鎖被釋放,但那永遠不會發生。和往常一樣,這個問題在SuspendResume2里得到了解決,它并不同步整個run()方法,而是采用了一個單獨的同步change()方法。
  對于Java 1.2,大家應注重suspend()和resume()已獲得強烈反對,因為suspend()包含了對象鎖,所以極易出現“死鎖”現象。換言之,很輕易就會看到許多被鎖住的對象在傻乎乎地等待對方。這會造成整個應用程序的“凝固”。盡管在一些老程序中還能看到它們的蹤跡,但在你寫自己的程序時,無論如何都應避免。本章稍后就會講述正確的方案是什么。
  3. 等待和通知
  通過前兩個例子的實踐,我們知道無論sleep()還是suspend()都不會在自己被調用的時候解除鎖定。需要用到對象鎖時,請務必注重這個問題。在另一方面,wait()方法在被調用時卻會解除鎖定,這意味著可在執行wait()期間調用線程對象中的其他同步方法。但在接著的兩個類中,我們看到run()方法都是“同步”的。在wait()期間,Peeker仍然擁有對同步方法的完全訪問權限。這是由于wait()在掛起內部調用的方法時,會解除對象的鎖定。
  我們也可以看到wait()的兩種形式。第一種形式采用一個以毫秒為單位的參數,它具有與sleep()中相同的含義:暫停這一段規定時間。區別在于在wait()中,對象鎖已被解除,而且能夠自由地退出wait(),因為一個notify()可強行使時間流逝。
  第二種形式不采用任何參數,這意味著wait()會持續執行,直到notify()介入為止。而且在一段時間以后,不會自行中止。
  wait()和notify()比較非凡的一個地方是這兩個方法都屬于基礎類Object的一部分,不象

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩美女中文字幕| xvideos亚洲人网站| 日韩精品在线免费| 亚洲精品97久久| 亚洲第一网站男人都懂| 久久综合亚洲社区| 在线播放国产精品| 日韩精品免费一线在线观看| 国产一区私人高清影院| 欧美精品videos性欧美| 亚洲欧美中文日韩在线| 亚洲日本成人女熟在线观看| 亚洲欧美日韩第一区| 清纯唯美亚洲激情| 亚洲天堂色网站| 亚洲女人初尝黑人巨大| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲色无码播放| 久久琪琪电影院| 久久久国产一区二区三区| 国产精品激情av电影在线观看| 亚洲成人久久久| 日av在线播放中文不卡| 成人国产在线激情| 亚洲va久久久噜噜噜久久天堂| 欧美日韩aaaa| 成年人精品视频| 2019av中文字幕| 欧洲成人在线视频| 国产丝袜视频一区| 性金发美女69hd大尺寸| 欧美日韩国产123| 久久91超碰青草是什么| 亚洲成人av片在线观看| 亚洲国产91精品在线观看| 亚洲精选一区二区| 欧美成人午夜剧场免费观看| 最新的欧美黄色| 欧美激情二区三区| 国产乱人伦真实精品视频| 日本免费久久高清视频| 中文字幕国产精品久久| 国产精品久久久久不卡| 欧美性猛交xxxxx水多| 国产ts人妖一区二区三区| 国产成人精品视| 国产欧美日韩免费| 日韩经典中文字幕| 欧美精品情趣视频| 久久亚洲国产精品成人av秋霞| 在线播放国产一区中文字幕剧情欧美| 伊人久久免费视频| 91色p视频在线| 一区二区三区四区在线观看视频| 欧美成年人在线观看| 91精品成人久久| 久久久国产精彩视频美女艺术照福利| 精品久久久999| 国产成人一区二区| 91黑丝在线观看| 精品亚洲一区二区三区四区五区| 亚洲深夜福利在线| 国产精品日日摸夜夜添夜夜av| 国产黑人绿帽在线第一区| 国产精品jvid在线观看蜜臀| 亚洲图中文字幕| 亚洲毛片在线看| 国产精品无av码在线观看| 欧美成人精品h版在线观看| 精品在线观看国产| 欧美中文字幕视频| 国产成人一区二区在线| 91亚洲精品在线| 国产成人精品综合| 成人精品视频久久久久| 午夜免费久久久久| 欧美激情视频在线免费观看 欧美视频免费一| 91精品视频在线播放| 国产成人综合一区二区三区| 欧美激情影音先锋| 欧美另类在线观看| 色先锋资源久久综合5566| 国产精品美女免费视频| 亚洲性生活视频| 国产亚洲精品一区二区| 青草青草久热精品视频在线观看| 成人福利在线观看| 亚洲一区二区免费在线| 欧美亚洲视频在线看网址| 免费成人高清视频| 国产精品久久久久久久久久久不卡| 国外成人在线直播| 国产精品一久久香蕉国产线看观看| 亚洲精品免费在线视频| 成人动漫网站在线观看| 中文字幕av一区| 最近中文字幕2019免费| 欧美日韩国产一区在线| 亚洲免费福利视频| 中文字幕精品—区二区| 欧美亚洲国产精品| 欧美激情一区二区三区久久久| 亚洲欧美综合v| 久久久久久久久久国产精品| 欧美性少妇18aaaa视频| 亚洲夜晚福利在线观看| 最新亚洲国产精品| 成人黄色免费网站在线观看| 91在线免费网站| 亚洲激情视频在线观看| 国产成人精品a视频一区www| 久久人人爽人人爽人人片亚洲| 国产性猛交xxxx免费看久久| 成人h猎奇视频网站| 亚洲aa在线观看| 精品日韩中文字幕| 亚洲欧美日韩久久久久久| 久久亚洲影音av资源网| 日韩av免费在线看| 国产亚洲一级高清| 2019精品视频| 国产成人一区三区| 国产91热爆ts人妖在线| 国产精品视频大全| 国产精品99蜜臀久久不卡二区| 国产精品久久999| 国语自产精品视频在线看| 少妇精69xxtheporn| 色婷婷综合成人| 亚洲男人天堂网| 日韩在线不卡视频| 久久久91精品国产一区不卡| 超碰91人人草人人干| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲小视频在线| 欧美午夜性色大片在线观看| 国产97色在线|日韩| 亚洲国产一区自拍| 国产精品久久999| 中文字幕日本精品| 欧美一区在线直播| 亚洲黄色免费三级| 欧美在线欧美在线| 欧美富婆性猛交| 欧美激情18p| 亚洲国产精品va在线观看黑人| 91视频88av| 国产精品成人一区二区| 国产精品久久久久免费a∨大胸| 日韩在线精品一区| 日韩精品在线观看一区二区| 在线亚洲午夜片av大片| 日本高清久久天堂| 色先锋资源久久综合5566| 欧美高清不卡在线| 日韩在线www| 成人高清视频观看www| 国产精品一区二区电影| 欧美在线性爱视频| 97视频免费看| 亚洲一区中文字幕在线观看| 91在线观看免费高清完整版在线观看| 日韩精品免费电影| 欧美裸体男粗大视频在线观看|