久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

JAVA多線程同步wait、notify,、synchronized

 dddTTLee 2010-11-26

 

1  wait方法:
        該方法屬于Object的方法,,wait方法的作用是使得當(dāng)前調(diào)用wait方法所在部分(代碼塊)的線程停止執(zhí)行,并釋放當(dāng)前獲得的調(diào)用wait所在的代碼塊的鎖,,并在其他線程調(diào)用notify或者notifyAll方法時(shí)恢復(fù)到競(jìng)爭(zhēng)鎖狀態(tài)(一旦獲得鎖就恢復(fù)執(zhí)行),。
        調(diào)用wait方法需要注意幾點(diǎn):
        第一點(diǎn):wait被調(diào)用的時(shí)候必須在擁有鎖(即synchronized修飾的)的代碼塊中。
        第二點(diǎn):恢復(fù)執(zhí)行后,,從wait的下一條語(yǔ)句開(kāi)始執(zhí)行,,因而wait方法總是應(yīng)當(dāng)在while循環(huán)中調(diào)用,以免出現(xiàn)恢復(fù)執(zhí)行后繼續(xù)執(zhí)行的條件不滿足卻繼續(xù)執(zhí)行的情況,。
        第三點(diǎn):若wait方法參數(shù)中帶時(shí)間,,則除了notify和notifyAll被調(diào)用能激活處于wait狀態(tài)(等待狀態(tài))的線程進(jìn)入鎖競(jìng)爭(zhēng)外,在其他線程中interrupt它或者參數(shù)時(shí)間到了之后,,該線程也將被激活到競(jìng)爭(zhēng)狀態(tài),。
        第四點(diǎn):wait方法被調(diào)用的線程必須獲得之前執(zhí)行到wait時(shí)釋放掉的鎖重新獲得才能夠恢復(fù)執(zhí)行。

2  notify方法和notifyAll方法:
        notify方法通知調(diào)用了wait方法,,但是尚未激活的一個(gè)線程進(jìn)入線程調(diào)度隊(duì)列(即進(jìn)入鎖競(jìng)爭(zhēng)),,注意不是立即執(zhí)行。并且具體是哪一個(gè)線程不能保證,。另外一點(diǎn)就是被喚醒的這個(gè)線程一定是在等待wait所釋放的鎖,。
        notifyAll方法則喚醒所有調(diào)用了wait方法,尚未激活的進(jìn)程進(jìn)入競(jìng)爭(zhēng)隊(duì)列,。

3 synchronized關(guān)鍵字:
        第一點(diǎn):synchronized用來(lái)標(biāo)識(shí)一個(gè)普通方法時(shí),,表示一個(gè)線程要執(zhí)行該方法,,必須取得該方法所在的對(duì)象的鎖
        第二點(diǎn):synchronized用來(lái)標(biāo)識(shí)一個(gè)靜態(tài)方法時(shí),,表示一個(gè)線程要執(zhí)行該方法,,必須獲得該方法所在的類的類鎖
        第三點(diǎn):synchronized修飾一個(gè)代碼塊,。類似這樣:synchronized(obj) { //code.... },。表示一個(gè)線程要執(zhí)行該代碼塊,必須獲得obj的鎖,。這樣做的目的是減小鎖的粒度,,保證當(dāng)不同塊所需的鎖不沖突時(shí)不用對(duì)整個(gè)對(duì)象加鎖。利用零長(zhǎng)度的byte數(shù)組對(duì)象做obj非常經(jīng)濟(jì),。

4 atomic action(原子操作):
        在JAVA中,,以下兩點(diǎn)操作是原子操作。但是c和c++中并不如此,。
        第一點(diǎn):對(duì)引用變量和除了long和double之外的原始數(shù)據(jù)類型變量進(jìn)行讀寫,。
        第二點(diǎn):對(duì)所有聲明為volatile的變量(包括long和double)的讀寫。
        另外:在java.util.concurrent和java.util.concurrent.atomic包中提供了一些不依賴于同步機(jī)制的線程安全的類和方法,。



5 一個(gè)例子,,該例子模仿多人存取同一個(gè)賬戶:
Account類:
package com.synchronize;

import java.util.HashMap;
import java.util.Iterator;

public class Account {
    private static HashMap<String, Integer> m = new HashMap<String, Integer>();
    private static long times = 0;
    static {
        m.put("ren", 1000);
    }

    public synchronized void save(String name, int num) {
        long tempTime = times++;
        System.out.println("第 " + tempTime + " 次存儲(chǔ)" + num + "之前" + name    + "的余額為:" + m.get(name));
        m.put(name, m.get(name) + num);
        this.notify();
        System.out.println("第 " + tempTime + " 次存儲(chǔ)" + num + "之后" + name + "的余額為:" + m.get(name));
    }

    public static int get(String name) {
        return m.get(name);
    }

    /**
     * 注意wait的用法,必須在loop中,,必須在擁有鎖的代碼塊中,。 前者是當(dāng)被notify的時(shí)候要重新進(jìn)行條件判斷,后者是為了釋放鎖,。
     *
     * @param name
     * @param num
     */
    public synchronized void load(String name, int num) {
        long tempTime = times++;
        System.out.println("第 " + tempTime + " 次提取" + num + "之前" + name + "的余額為:" + m.get(name));

        try {
            while (m.get(name) < num) {
                System.out.println("第 " + tempTime + " 次提取" + "余額" + m.get(name) + "不足,,開(kāi)始等待wait。");
                this.wait();
                System.out.println("第 " + tempTime + " 次提取操作被喚醒");
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        m.put(name, m.get(name) - num);
        System.out.println("第 " + tempTime + " 次提取" + num + "之后" + name + "的余額為:" + m.get(name));
    }
}


User類:
package com.synchronize;

/**
 * 這里注意runnable接口的線程是怎么實(shí)例化的,。new Thread(new User())
 * 這里成功展示了多個(gè)用戶存取同一個(gè)賬戶的多線程實(shí)例,,通過(guò)多線程同步,保證了安全的執(zhí)行,。
 * @author abc
 *
 */
public class User implements Runnable {
    private static Account account = new Account();
    private final int id;
   
    User(int i){
        id=i;
    }
   
    public void run() {
        int tempMoney = 100;
        account.load("ren", tempMoney);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        account.save("ren", 100);
        System.out.println("線程"+id+"完畢========================================================");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new User(i)).start();
        }
    }
}
 

 
6、下面是自己寫的,,一個(gè)經(jīng)典的消費(fèi)者和生產(chǎn)者的例子:
1,、ObjLock.java
 
/**
 * 生產(chǎn)者(producer)與消費(fèi)者(consumer)問(wèn)題
 * 說(shuō)明事物鎖與多線程同步
 * 生產(chǎn)者生產(chǎn),消費(fèi)者消費(fèi),規(guī)則:但當(dāng)庫(kù)存為0時(shí),消費(fèi)者要消費(fèi)是不行的;
 * 但當(dāng)庫(kù)存為上限(這里是10)時(shí),生產(chǎn)者也不能生產(chǎn)
 */
public class ObjLock implements Runnable {
 private int count = 0;   //產(chǎn)品數(shù)
 
 private int locknum = 0; //上鎖的線程數(shù)
 
 public ObjLock(int n){
  this.count = n;
 }
 
 //生產(chǎn)
 public synchronized void produce(){
  while(count == 10){
   locknum ++;
   try {
    wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  count ++;
  if(locknum > 0)
   locknum --;
  notify();
 }
 
 //消費(fèi)
 public synchronized void consume(){
  while(count == 0){
   locknum ++;
   try {
    wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  count --;
  if(locknum > 0)
   locknum --;
  notify();
 }
 
 public void run() {
  while(true){
   if(Thread.currentThread().getName().substring(0, 8).equals("producer"))
    produce();
   else if(Thread.currentThread().getName().substring(0, 8).equals("consumer"))
    consume();
   System.out.println(Thread.currentThread().getName() + ": " + count + " ,locknum: " + locknum);
  }
 }
}
2,、TestObjLock測(cè)試類
public static void main(String[] args) {
  ObjLock ol = new ObjLock(1);
  Thread th1 = new Thread(ol,"producer");
  Thread th2 = new Thread(ol,"consumer");
  Thread th3 = new Thread(ol,"producer");
  Thread th4 = new Thread(ol,"consumer");
  Thread th5 = new Thread(ol,"producer");
  Thread th6 = new Thread(ol,"consumer");
  
  th1.start();
  th2.start();
  th3.start();
  th4.start();
  th5.start();
  th6.start();
 }
 
注意:這里所以生產(chǎn)和消費(fèi)都必須有notify(),,避免死鎖。不信的可以去掉其中一個(gè),,可以測(cè)試實(shí)現(xiàn),。
我記得大學(xué)學(xué)數(shù)據(jù)庫(kù)的時(shí)候,,也有說(shuō)到這類問(wèn)題。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多