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

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

反應靈敏的用戶界面

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

  反應靈敏的用戶界面
  作為我們的起點,請思考一個需要執行某些CPU密集型計算的程序。由于CPU“全心全意”為那些計算服務,所以對用戶的輸入十分遲鈍,幾乎沒有什么反應。在這里,我們用一個合成的applet/application(程序片/應用程序)來簡單顯示出一個計數器的結果:
  //: Counter1.java
  // A non-responsive user interface
  package c14;
  import java.awt.*;
  import java.awt.event.*;
  import java.applet.*;
  public class Counter1 extends Applet {
   PRivate int count = 0;
   private Button
    onOff = new Button("Toggle"),
    start = new Button("Start");
   private TextField t = new TextField(10);
   private boolean runFlag = true;
   public void init() {
    add(t);
    start.addActionListener(new StartL());
    add(start);
    onOff.addActionListener(new OnOffL());
    add(onOff);
   }
   public void go() {
    while (true) {
     try {
      Thread.currentThread().sleep(100);
     } catch (InterruptedException e){}
     if(runFlag)
      t.setText(Integer.toString(count++));
    }
   }
   class StartL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
     go();
    }
   }
   class OnOffL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
     runFlag = !runFlag;
    }
   }
   public static void main(String[] args) {
    Counter1 applet = new Counter1();
    Frame aFrame = new Frame("Counter1");
    aFrame.addWindowListener(
     new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
       System.exit(0);
      }
     });
    aFrame.add(applet, BorderLayout.CENTER);
    aFrame.setSize(300,200);
    applet.init();
    applet.start();
    aFrame.setVisible(true);
   }
  } //
  在這個程序中,AWT和程序片代碼都應是大家熟悉的,第13章對此已有很具體的交待。go()方法正是程序全心全意服務的對待:將當前的count(計數)值置入TextField(文本字段)t,然后使count增值。
  go()內的部分無限循環是調用sleep()。sleep()必須同一個Thread(線程)對象關聯到一起,而且似乎每個應用程序都有部分線程同它關聯(事實上,Java本身就是建立在線程基礎上的,肯定有一些線程會伴隨我們寫的應用一起運行)。所以無論我們是否明確使用了線程,都可利用Thread.currentThread()產生由程序使用的當前線程,然后為那個線程調用sleep()。注重,Thread.currentThread()是Thread類的一個靜態方法。
  注重sleep()可能“擲”出一個InterruptException(中斷違例)——盡管產生這樣的違例被認為是中止線程的一種“惡意”手段,而且應該盡可能地杜絕這一做法。再次提醒大家,違例是為異常情況而產生的,而不是為了正常的控制流。在這里包含了對一個“睡眠”線程的中斷,以支持未來的一種語言特性。
  一旦按下start按鈕,就會調用go()。研究一下go(),你可能會很自然地(就象我一樣)認為它該支持多線程,因為它會進入“睡眠”狀態。也就是說,盡管方法本身“睡著”了,CPU仍然應該忙于監視其他按鈕“按下”事件。但有一個問題,那就是go()是永遠不會返回的,因為它被設計成一個無限循環。這意味著actionPerformed()根本不會返回。由于在第一個按鍵以后便陷入actionPerformed()中,所以程序不能再對其他任何事件進行控制(假如想出來,必須以某種方式“殺死”進程——最簡便的方式就是在控制臺窗口按Ctrl+C鍵)。
  這里最基本的問題是go()需要繼續執行自己的操作,而與此同時,它也需要返回,以便actionPerformed()能夠完成,而且用戶界面也能繼續響應用戶的操作。但對象go()這樣的傳統方法來說,它卻不能在繼續的同時將控制權返回給程序的其他部分。這聽起來似乎是一件不可能做到的事情,就象CPU必須同時位于兩個地方一樣,但線程可以解決一切?!熬€程模型”(以及Java中的編程支持)是一種程序編寫規范,可在單獨一個程序里實現幾個操作的同時進行。根據這一機制,CPU可為每個線程都分配自己的一部分時間。每個線程都“感覺”自己好象擁有整個CPU,但CPU的計算時間實際卻是在所有線程間分攤的。
  線程機制多少降低了一些計算效率,但無論程序的設計,資源的均衡,還是用戶操作的方便性,都從中獲得了巨大的利益。綜合考慮,這一機制是非常有價值的。當然,假如本來就安裝了多塊CPU,那么操作系統能夠自行決定為不同的CPU分配哪些線程,程序的總體運行速度也會變得更快(所有這些都要求操作系統以及應用程序的支持)。多線程和多任務是充分發揮多處理機系統能力的一種最有效的方式。
  1 從線程繼續
  為創建一個線程,最簡單的方法就是從Thread類繼續。這個類包含了創建和運行線程所需的一切東西。Thread最重要的方法是run()。但為了使用run(),必須對其進行過載或者覆蓋,使其能充分按自己的吩咐行事。因此,run()屬于那些會與程序中的其他線程“并發”或“同時”執行的代碼。
  下面這個例子可創建任意數量的線程,并通過為每個線程分配一個獨一無二的編號(由一個靜態變量產生),從而對不同的線程進行跟蹤。Thread的run()方法在這里得到了覆蓋,每通過一次循環,計數就減1——計數為0時則完成循環(此時一旦返回run(),線程就中止運行)。
  //: SimpleThread.java
  // Very simple Threading example
  public class SimpleThread extends Thread {
   private int countDown = 5;
   private int threadNumber;
   private static int threadCount = 0;
   public SimpleThread() {
    threadNumber = ++threadCount;
    System.out.println("Making " + threadNumber);
   }
   public void run() {
    while(true) {
     System.out.println("Thread " +
      threadNumber + "(" + countDown + ")");
     if(--countDown == 0) return;
    }
   }
   public static void main(String[] args) {
    for(int i = 0; i < 5; i++)
     new SimpleThread().start();
    System.out.println("All Threads Started");
   }
  }
  run()方法幾乎肯定含有某種形式的循環——它們會一直持續到線程不再需要為止。因此,我們必須規定特定的條件,以便中斷并退出這個循環(或者在上述的例子中,簡單地從run()返回即可)。run()通常采用一種無限循環的形式。也就是說,通過阻止外部發出對線程的stop()或者destroy()調用,它會永遠運行下去(直到程序完成)。
  在main()中,可看到創建并運行了大量線程。Thread包含了一個非凡的方法,叫作start(),它的作用是對線程進行非凡的初始化,然后調用run()。所以整個步驟包括:調用構建器來構建對象,然后用start()配置線程,再調用run()。假如不調用start()——假如適當的話,可在構建器那樣做——線程便永遠不會啟動。
  下面是該程序某一次運行的輸出(注重每次運行都會不同):
  Making 1
  Making 2
  Making 3
  Making 4
  Making 5
  Thread 1(5)
  Thread 1(4)
  Thread 1(3)
  Thread 1(2)
  Thread 2(5)
  Thread 2(4)
  Thread 2(3)
  Thread 2(2)
  Thread 2(1)
  Thread 1(1)
  All Threads Started
  Thread 3(5)
  Thread 4(5)
  Thread 4(4)
  Thread 4(3)
  Thread 4(2)
  Thread 4(1)
  Thread 5(5)
  Thread 5(4)
  Thread 5(3)
  Thread 5(2)
  Thread 5(1)
  Thread 3(4)
  Thread 3(3)
  Thread 3(2)
  Thread 3(1)
  可注重到這個例子中到處都調用了sleep(),然而輸出結果指出每個線程都獲得了屬于自己的那一部分CPU執行時間。從中可以看出,盡管sleep()依靠一個線程的存在來執行,但卻與答應或禁止線程無關。它只不過是另一個不同的方法而已。
  亦可看出線程并不是按它們創建時的順序運行的。事實上,CPU處理一個現有線程集的順序是不確定的——除非我們親自介入,并用Thread的setPriority()方法調整它們的優先級。
  main()創建Thread對象時,它并未捕捉任何一個對象的句柄。普通對象對于垃圾收集來說是一種“公平競賽”,但線程卻并非如此。每個線程都會“注冊”自己,所以某處實際存在著對它的一個引用。這樣一來,垃圾收集器便只好對它“瞠目以對”了。
  2 針對用戶界面的多線程
  現在,我們也許能用一個線程解決在Counter1.java中出現的問題。采用的一個技巧便是在一個線程的run()方法中放置“子任務”——亦即位于go()內的循環。一旦用戶按下Start按鈕,線程就會啟動,但馬上結束線程的創建。這樣一來,盡管線程仍在運行,但程序的主要工作卻能得以繼續(等候并響應用戶界面的事件)。下面是具體的代碼:
  //: Counter2.java
  // A responsive user interface with threads
  import java.awt.*;
  import java.awt.event.*;<

上一篇:共享有限的資源

下一篇:為何會堵塞

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人免费xxxxx在线观看| 91国产一区在线| 精品综合久久久久久97| 国产91精品网站| 91夜夜揉人人捏人人添红杏| 成人福利在线视频| 久久久国产视频| 国产日韩欧美日韩大片| 日本在线观看天堂男亚洲| 日韩欧美大尺度| 2019中文字幕免费视频| 91精品国产色综合| 精品久久久久久久久久| 视频一区视频二区国产精品| 国产大片精品免费永久看nba| 国产精品户外野外| 国产va免费精品高清在线| 成人动漫网站在线观看| 亚洲精品中文字| 亚洲欧美日韩成人| 俺去亚洲欧洲欧美日韩| 日韩av综合网| 日韩精品中文字幕有码专区| 亚洲美女自拍视频| 国产精品av在线播放| 国产精品视频一区国模私拍| 一夜七次郎国产精品亚洲| 国产精品白丝av嫩草影院| 国产精品久久久久久久久久| 97视频在线看| 亚洲区在线播放| 国产亚洲一级高清| 亚洲欧美日韩爽爽影院| 久久精品国产v日韩v亚洲| 欧美成人久久久| 欧美在线视频网站| 亚洲第一精品久久忘忧草社区| 日韩精品视频观看| 成人福利视频在线观看| 麻豆乱码国产一区二区三区| 成人黄色在线观看| 亚洲国产成人91精品| 8050国产精品久久久久久| 亚洲国产古装精品网站| 欧美主播福利视频| 欧美性猛交xxxx富婆| 91精品视频大全| 国产精品白丝av嫩草影院| 亚洲成年人在线播放| 久久精品国产96久久久香蕉| 久久91亚洲精品中文字幕| 综合av色偷偷网| 精品久久久久久中文字幕| 国产97色在线| 欧美成人精品不卡视频在线观看| 97精品一区二区视频在线观看| 久久成人精品视频| 欧美日韩电影在线观看| 亚洲免费视频在线观看| 国产精品免费网站| 成人妇女免费播放久久久| 国产精品毛片a∨一区二区三区|国| 992tv成人免费视频| 欧美激情一级欧美精品| 91在线观看免费网站| 91久久综合亚洲鲁鲁五月天| 亚洲精品有码在线| 欧美性高跟鞋xxxxhd| 国产成人中文字幕| 欧美性一区二区三区| 91精品国产高清自在线| 中文字幕亚洲国产| 国产精品偷伦视频免费观看国产| 日本精品久久中文字幕佐佐木| 精品成人69xx.xyz| 日韩精品在线观看一区| 国产精品久久久久久久av大片| 日韩精品一区二区视频| 亚洲大尺度美女在线| 成人久久久久爱| 欧美高清视频免费观看| 久久久久成人网| 91亚洲精品久久久久久久久久久久| 国产欧美日韩精品专区| 成人精品一区二区三区电影免费| 久久中文字幕一区| 亚洲欧美在线一区二区| 国产综合香蕉五月婷在线| 日韩欧美中文字幕在线播放| 好吊成人免视频| 精品成人国产在线观看男人呻吟| 亚洲综合在线做性| 国产免费久久av| 日韩精品久久久久久久玫瑰园| 在线观看欧美日韩| 韩国美女主播一区| 欧美大片va欧美在线播放| 欧美日韩国产影院| 欧美福利视频在线| 久久久久久久久综合| 久久精品国产精品亚洲| 91精品国产九九九久久久亚洲| 亚洲人精选亚洲人成在线| 午夜精品一区二区三区在线视频| 久久偷看各类女兵18女厕嘘嘘| 欧美激情久久久久久| 高清欧美性猛交xxxx| 欧美寡妇偷汉性猛交| 国产精品久久综合av爱欲tv| 亚洲第一男人天堂| 成人av.网址在线网站| 日本一欧美一欧美一亚洲视频| 国产精品久久久久久久9999| 91高潮在线观看| 亚洲一区二区精品| 91高清视频免费| 日本精品视频在线| 日本成人激情视频| 欧美精品免费在线| 北条麻妃一区二区在线观看| 国产精品无av码在线观看| 欧美成在线视频| 国产精品白丝jk喷水视频一区| 国产成人一区二区三区电影| 在线视频日本亚洲性| 亚洲精品国产成人| 国产精品r级在线| 国产欧美最新羞羞视频在线观看| 亚洲sss综合天堂久久| 91chinesevideo永久地址| 亚洲综合日韩中文字幕v在线| 日韩av影视在线| 国产精品免费久久久| 国产美女精品免费电影| 欧美亚洲视频在线观看| 蜜臀久久99精品久久久久久宅男| 亚洲va国产va天堂va久久| 国产亚洲美女精品久久久| 国产97免费视| 欧美在线免费观看| 日韩精品中文字幕在线| 国产精品久久久久久av福利软件| 亚洲一区二区中文| 欧美性猛交xxxxx免费看| 久久精品一区中文字幕| 91久久久久久久久久久| 国产69精品久久久久99| 91亚洲精品一区| 91精品在线看| 久久亚洲春色中文字幕| 国产日韩在线观看av| 亚洲国产成人在线播放| 91精品国产91久久久久久久久| 高清欧美性猛交xxxx黑人猛交| 正在播放亚洲1区| 亚洲精品欧美日韩专区| 国产精品福利片| 欧美人在线观看| 欧美资源在线观看| 久久成人一区二区| 亚洲已满18点击进入在线看片| 久久99热精品这里久久精品| 国产免费一区视频观看免费| 在线看欧美日韩|