熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java多線程實現異步調用

2013-11-23 19:46:17  來源: Java高級技術 

  在JAVA平台實現異步調用的角色有如下三個角色:調用者 提貨單 真實數據一個調用者在調用耗時操作不能立即返回數據時先返回一個提貨單然後在過一斷時間後憑提貨單來獲取真正的數據去蛋糕店買蛋糕不需要等蛋糕做出來(假設現做要很長時間)只需要領個提貨單就可以了(去干別的事情)等到蛋糕做好了再拿提貨單取蛋糕就可以了public class Main { public static void main(String[] args) {

  Systemoutprintln(main BEGIN);

  Host host = new Host();

  Data data = hostrequest( A);

  Data data = hostrequest( B);

  Data data = hostrequest( C);

  Systemoutprintln(main otherJob BEGIN);

  try {

  Threadsleep();

  } catch (InterruptedException e) {

  }

  Systemoutprintln(main otherJob END);

  Systemoutprintln(data = + datagetContent());

  Systemoutprintln(data = + datagetContent());

  Systemoutprintln(data = + datagetContent());

  Systemoutprintln(main END);

  }

  }

  這裡的main類就相當於顧客host就相當於蛋糕店顧客向蛋糕店定蛋糕就相當於發請求request返回的數據data是FutureData的實例就相當於提貨單而不是真正的蛋糕在過一段時間後(sleep一段時間後)調用datagetContent()也就是拿提貨單獲取執行結果

  下面來看一下顧客定蛋糕後蛋糕店做了什麼

  public class Host {

  public Data request(final int count final char c) {

  Systemoutprintln(request( + count + + c + ) BEGIN);

  // () 建立FutureData的實體

  final FutureData future = new FutureData();

  // () 為了建立RealData的實體啟動新的線程

  new Thread() {

  public void run() {

  //在匿名內部類中使用countfuturec

  RealData realdata = new RealData(count c);

  futuresetRealData(realdata);

  }

  }start();

  Systemoutprintln(request( + count + + c + ) END);

  // () 取回FutureData實體作為傳回值

  return future;

  }

  }

  host(蛋糕店)在接到請求後先生成了提貨單FutureData的實例future然後命令蛋糕師傅RealData去做蛋糕realdata相當於起個線程去做蛋糕了然後host返回給顧客的僅僅是提貨單future而不是蛋糕當蛋糕做好後蛋糕師傅才能給對應的提貨單蛋糕也就是futuresetRealData(realdata)

  下面來看看蛋糕師傅是怎麼做蛋糕的

  建立一個字符串包含count個c字符為了表現出犯法需要花費一些時間使用了sleep

  public class RealData implements Data { private final String content;

  public RealData(int count char c) {

  Systemoutprintln(making RealData( + count + + c + ) BEGIN);

  char[] buffer = new char[count];

  for (int i = ; i < count; i++) {

  buffer[i] = c;

  try {

  Threadsleep();

  } catch (InterruptedException e) {

  }

  }

  Systemoutprintln(making RealData( + count + + c + ) END);

  ntent = new String(buffer);

  }

  public String getContent() {

  return content;

  }

  }

  現在來看看提貨單future是怎麼與蛋糕content對應的:

  public class FutureData implements Data { private RealData realdata = null;

  private boolean ready = false;

  public synchronized void setRealData(RealData realdata) {

  if (ready) {

  return; // 防止setRealData被調用兩次以上

  }

  thisrealdata = realdata;

  thisready = true;

  notifyAll();

  }

  public synchronized String getContent() {

  while (!ready) {

  try {

  wait();

  } catch (InterruptedException e) {

  }

  }

  return realdatagetContent();

  }

  }

  顧客做完自己的事情後會拿著自己的提貨單來取蛋糕

  Systemoutprintln(data = + datagetContent());

  這時候如果蛋糕沒做好就只好等了

  while (!ready) { try {

  wait();

  } catch (InterruptedException e) {

  }

  //等做好後才能取到

  return realdatagetContent();

  程序分析

  對於每個請求host都會生成一個線程這個線程負責生成顧客需要的蛋糕在等待一段時間以後如果蛋糕還沒有做好顧客還必須等待直到蛋糕被做好也就是

  futuresetRealData(realdata); 執行以後顧客才能拿走蛋糕

  每個線程只是專門負責制作特定顧客所需要的蛋糕也就是顧客A對應著蛋糕師傅A顧客B對應著蛋糕師傅B即使顧客B的蛋糕被先做好了顧客A也只能等待蛋糕師傅A把蛋糕做好換句話說顧客之間沒有競爭關系

  類FutureData的兩個方法被設置為synchronized實際上蛋糕師傅A與顧客A之間的互斥關系也就是顧客A必須等待蛋糕師傅A把蛋糕做好後才能拿走而與蛋糕師傅B是否做好了蛋糕沒有關系


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27425.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.