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

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

Java如何共享資源

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

  對一種非凡的資源——對象中的內存——java提供了內建的機制來防止它們的沖突。由于我們通常將數據元素設為從屬于PRivate(私有)類,然后只通過方法訪問那些內存,所以只需將一個特定的方法設為synchronized(同步的),便可有效地防止沖突。在任何時刻,只可有一個線程調用特定對象的一個synchronized方法(盡管那個線程可以調用多個對象的同步方法)。下面列出簡單的synchronized方法:
  synchronized void f() { /* ... */ }
  synchronized void g() { /* ... */ }
  每個對象都包含了一把鎖(也叫作“監視器”),它自動成為對象的一部分(不必為此寫任何非凡的代碼)。調用任何synchronized方法時,對象就會被鎖定,不可再調用那個對象的其他任何synchronized方法,除非第一個方法完成了自己的工作,并解除鎖定。在上面的例子中,假如為一個對象調用f(),便不能再為同樣的對象調用g(),除非f()完成并解除鎖定。因此,一個特定對象的所有synchronized方法都共享著一把鎖,而且這把鎖能防止多個方法對通用內存同時進行寫操作(比如同時有多個線程)。
  每個類也有自己的一把鎖(作為類的Class對象的一部分),所以synchronized static方法可在一個類的范圍內被相互間鎖定起來,防止與static數據的接觸。
  注重假如想保護其他某些資源不被多個線程同時訪問,可以強制通過synchronized方訪問那些資源。
  1. 計數器的同步
  裝備了這個新要害字后,我們能夠采取的方案就更靈活了:可以只為TwoCounter中的方法簡單地使用synchronized要害字。下面這個例子是對前例的改版,其中加入了新的要害字:
  //: Sharing2.java
  // Using the synchronized keyWord to prevent
  // multiple access to a particular resource.
  import java.awt.*;
  import java.awt.event.*;
  import java.applet.*;
  class TwoCounter2 extends Thread {
   private boolean started = false;
   private TextField
   t1 = new TextField(5),
   t2 = new TextField(5);
   private Label l =
   new Label("count1 == count2");
   private int count1 = 0, count2 = 0;
   public TwoCounter2(Container c) {
   Panel p = new Panel();
   p.add(t1);
   p.add(t2);
   p.add(l);
   c.add(p);
   }
   public void start() {
   if(!started) {
   started = true;
   super.start();
   }
   }
   public synchronized void run() {
   while (true) {
   t1.setText(Integer.toString(count1++));
   t2.setText(Integer.toString(count2++));
   try {
   sleep(500);
   } catch (InterruptedException e){}
   }
   }
   public synchronized void synchTest() {
   Sharing2.incrementAccess();
   if(count1 != count2)
   l.setText("Unsynched");
   }
  }
  class Watcher2 extends Thread {
   private Sharing2 p;
   public Watcher2(Sharing2 p) {
   this.p = p;
   start();
   }
   public void run() {
   while(true) {
   for(int i = 0; i < p.s.length; i++)
   p.s[i].synchTest();
   try {
   sleep(500);
   } catch (InterruptedException e){}
   }
   }
  }
  public class Sharing2 extends Applet {
   TwoCounter2[] s;
   private static int accessCount = 0;
   private static TextField aCount =
   new TextField("0", 10);
   public static void incrementAccess() {
   accessCount++;
   aCount.setText(Integer.toString(accessCount));
   }
   private Button
   start = new Button("Start"),
   observer = new Button("Observe");
   private boolean isApplet = true;
   private int numCounters = 0;
   private int numObservers = 0;
   public void init() {
   if(isApplet) {
   numCounters =
   Integer.parseInt(getParameter("size"));
   numObservers =
   Integer.parseInt(
   getParameter("observers"));
   }
   s = new TwoCounter2[numCounters];
   for(int i = 0; i < s.length; i++)
   s[i] = new TwoCounter2(this);
   Panel p = new Panel();
   start.addActionListener(new StartL());
   p.add(start);
   observer.addActionListener(new ObserverL());
   p.add(observer);
   p.add(new Label("Access Count"));
   p.add(aCount);
   add(p);
   }
   class StartL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   for(int i = 0; i < s.length; i++)
   s[i].start();
   }
   }
   class ObserverL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   for(int i = 0; i < numObservers; i++)
   new Watcher2(Sharing2.this);
   }
   }
   public static void main(String[] args) {
   Sharing2 applet = new Sharing2();
   // This isn't an applet, so set the flag and
   // prodUCe the parameter values from args:
   applet.isApplet = false;
   applet.numCounters =
   (args.length == 0 ? 5 :
   Integer.parseInt(args[0]));
   applet.numObservers =
   (args.length < 2 ? 5 :
   Integer.parseInt(args[1]));
   Frame aFrame = new Frame("Sharing2");
   aFrame.addWindowListener(
   new WindowAdapter() {
   public void windowClosing(WindowEvent e){
   System.exit(0);
   }
   });
   aFrame.add(applet, BorderLayout.CENTER);
   aFrame.setSize(350, applet.numCounters *100);
   applet.init();
   applet.start();
   aFrame.setVisible(true);
   }
  }
  我們注重到無論run()還是synchTest()都是“同步的”。假如只同步其中的一個方法,那么另一個就可以自由忽視對象的鎖定,并可無礙地調用。所以必須記住一個重要的規則:對于訪問某個要害共享資源的所有方法,都必須把它們設為synchronized,否則就不能正常地工作。
  現在又碰到了一個新問題。Watcher2永遠都不能看到正在進行的事情,因為整個run()方法已設為“同步”。而且由于肯定要為每個對象運行run(),所以鎖永遠不能打開,而synchTest()永遠不會得到調用。之所以能看到這一結果,是因為accessCount根本沒有變化。
  為解決這個問題,我們能采取的一個辦法是只將run()中的一部分代碼隔離出來。想用這個辦法隔離出來的那部分代碼叫作“要害區域”,而且要用不同的方式來使用synchronized要害字,以設置一個要害區域。Java通過“同步塊”提供對要害區域的支持;這一次,我們用synchronized要害字指出對象的鎖用于對其中封閉的代碼進行同步。如下所示:
  synchronized(syncObject) {
   // This code can be accessed by only
   // one thread at a time, assuming all
   // threads respect syncObject's lock
  }
  在能進入同步塊之前,必須在synchObject上取得鎖。假如已有其他線程取得了這把鎖,塊便不能進入,必須等候那把鎖被釋放。
  可從整個run()中刪除synchronized要害字,換成用一個同步塊包圍兩個要害行,從而完成對Sharing2例子的修改。但什么對象應作為鎖來使用呢?那個對象已由synchTest()標記出來了——也就是當前對象(this)!所以修改過的run()方法象下面這個樣子:
  
   public void run() {
   while (true) {
   synchronized(this) {
   t1.setText(Integer.toString(count1++));
   t2.setText(Integer.toString(count2++));
   }
   try {
   sleep(500);
   } catch (InterruptedException e){}
   }
   }
  這是必須對Sharing2.java作出的唯一修改,我們會看到盡管兩個計數器永遠不會脫離同步(取決于答應Watcher什么時候檢查它們),但在run()執行期間,仍然向Watcher提供了足夠的訪問權限。
  當然,所有同步都取決于程序員是否勤奮:要訪問共享資源的每一部分代碼都必須封裝到一個適當的同步塊里。
  2. 同步的效率
  由于要為同樣的數據編寫兩個方法,所以無論如何都不會給人留下效率很高的印象。看來似乎更好的一種做法是將所有方法都設為自動同步,并完全消除synchronized要害字(當然,含有synchronized run()的例子顯示出這樣做是很不通的)。但它也揭示出獲取一把鎖并非一種“廉價”方案——為一次方法調用付出的代價(進入和退出方法,

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情国内偷拍| 在线丨暗呦小u女国产精品| 欧美激情小视频| 97热精品视频官网| 国产在线观看精品一区二区三区| 中文字幕亚洲一区二区三区五十路| 欧美日韩国产一区二区三区| 欧美天堂在线观看| 日韩在线免费观看视频| 在线观看欧美日韩国产| 少妇高潮 亚洲精品| 尤物九九久久国产精品的特点| 欧美大胆a视频| 国产精品免费福利| 国产剧情久久久久久| 国产精品女人久久久久久| 福利视频导航一区| 国产精品一区二区三区久久久| 中文字幕成人在线| 精品国产一区二区三区久久狼5月| 久久久综合av| 这里只有视频精品| 国产精品久久久久久久午夜| 韩国视频理论视频久久| 亚洲在线www| 在线视频免费一区二区| 亚洲国产精品字幕| 欧美激情18p| 久久精品国产99国产精品澳门| 久久精品亚洲94久久精品| 2019中文字幕全在线观看| 欧美性xxxx18| 亚洲老头老太hd| 欧美日韩高清在线观看| 亚洲欧美中文日韩在线v日本| 欧美一级大片在线观看| 国产一级揄自揄精品视频| 久久综合五月天| 精品国产一区二区三区久久久狼| 狠狠躁夜夜躁人人躁婷婷91| 欧美国产亚洲视频| 国产亚洲成av人片在线观看桃| 亚洲午夜色婷婷在线| 国产精品男人的天堂| 日韩av在线不卡| 欧美成人精品h版在线观看| 久久久精品久久| 亚洲最大av在线| 欧美丝袜一区二区| 狠狠综合久久av一区二区小说| 午夜精品久久久久久久白皮肤| 欧美超级免费视 在线| 国产成+人+综合+亚洲欧美丁香花| 97国产成人精品视频| 欧美在线观看视频| 国产亚洲精品久久久久动| 日韩福利视频在线观看| 国产精品久久一区主播| 欧美在线影院在线视频| 午夜精品久久17c| 在线激情影院一区| 日韩欧美亚洲成人| 国产在线播放91| 美女撒尿一区二区三区| 欧美国产中文字幕| 欧美日韩亚洲视频一区| 日韩在线视频观看正片免费网站| 国产精品久久久久高潮| 国产精品444| 欧美中文字幕在线| 88国产精品欧美一区二区三区| 欧美电影第一页| 亚洲电影免费观看高清| 中文字幕在线精品| 久久精彩免费视频| 成人免费视频97| 欧美大片免费观看| 欧美激情一级欧美精品| 国产欧美日韩中文字幕在线| 国产色综合天天综合网| 国产精品一二三视频| 国产美女扒开尿口久久久| 亚洲国产精品一区二区久| 欧美高清视频在线播放| 亚洲欧美综合精品久久成人| 欧美日韩亚洲高清| 欧美激情在线狂野欧美精品| 亚洲一区二区三区视频播放| 精品一区二区三区四区在线| 欧美激情xxxx| 国产欧美最新羞羞视频在线观看| 国产欧美欧洲在线观看| 亚洲国产成人久久综合一区| 国产精品视频导航| 91精品国产高清久久久久久久久| 日韩成人中文字幕| 久久久久久久久久久免费精品| 日韩国产欧美精品一区二区三区| 亚洲电影免费观看高清完整版在线| 91影视免费在线观看| 夜夜嗨av色一区二区不卡| 亚洲女人被黑人巨大进入al| 日韩欧美在线播放| 日韩av在线免播放器| 亚洲乱亚洲乱妇无码| 成人午夜在线视频一区| 国产成人综合精品在线| 91在线精品播放| 亚洲高清福利视频| 国产成人在线播放| 国产精品国产亚洲伊人久久| 亚洲精品久久久久久下一站| 久久久久久久电影一区| 综合久久五月天| 日韩中文字幕在线精品| 国产精欧美一区二区三区| 国产午夜精品一区二区三区| 欧洲亚洲在线视频| 91黑丝高跟在线| 国产视频精品一区二区三区| 97婷婷涩涩精品一区| 亚洲精品网站在线播放gif| 91亚洲精品在线观看| 久久国产精品久久久久久久久久| 日本韩国在线不卡| 色综合视频一区中文字幕| 欧美日韩国产丝袜另类| 日韩风俗一区 二区| 亚洲二区中文字幕| 97视频在线观看亚洲| 亚洲成人精品久久久| 一本色道久久综合亚洲精品小说| 亚洲va国产va天堂va久久| 成人有码在线视频| 亚洲国产黄色片| 伊人伊人伊人久久| 国产激情久久久| 午夜精品久久久久久久99黑人| 日韩精品在线观看视频| 日本久久久a级免费| 91精品国产一区| 亚洲最新av在线网站| 欧美激情日韩图片| 日韩中文字幕精品视频| 欧美激情视频网站| 久久中国妇女中文字幕| 久99久在线视频| 亚洲精品综合精品自拍| 国产精品高清网站| 欧美日韩午夜剧场| 疯狂欧美牲乱大交777| 成人疯狂猛交xxx| 久热精品视频在线观看一区| 久久99热精品这里久久精品| 国产亚洲一区二区在线| 亚洲自拍偷拍区| xxxxx成人.com| 91美女片黄在线观看游戏| 欧美一级视频免费在线观看| 亚洲已满18点击进入在线看片| 一本一本久久a久久精品综合小说| 欧美在线欧美在线| 日韩中文字幕免费看| 亚洲欧美在线第一页|