JAVA wait 和Notify方法研究

繼續來看bloghttp://blog.csdn.net/zyplus/article/details/6672775 java

Obj.wait(),與Obj.notify()必需要與synchronized(Obj)一塊兒使用,也就是wait,notify是針對已經獲取了Obj鎖進行操做,從語法角度來講就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語句塊內。從功能上來講wait就是說線程在獲取對象鎖後,主動釋放對象鎖,同時本線程休眠。直到有其它線程調用對象的notify()喚醒該線程,才能繼續獲取對象鎖,並繼續執行。相應的notify()就是對對象鎖的喚醒操做。但有一點須要注意的是notify()調用後,並非立刻就釋放對象鎖的,而是在相應的synchronized(){}語句塊執行結束,自動釋放鎖後,JVM會在wait()對象鎖的線程中隨機選取一線程,賦予其對象鎖,喚醒線程,繼續執行。這樣就提供了在線程間同步、喚醒的操做。Thread.sleep()Object.wait()兩者均可以暫停當前線程,釋放CPU控制權,主要的區別在於Object.wait()在釋放CPU同時,釋放了對象鎖的控制。」 ide

咱們來寫段測試數據:一個線程往MAP寫數據,另一個線程讀數據。 測試


package com.jdcloud.xue.gang.data.put.get; this


import java.util.HashMap; atom

import java.util.Map; spa

import java.util.concurrent.ExecutorService; .net

import java.util.concurrent.Executors; 線程

import java.util.concurrent.atomic.AtomicInteger; 調試


public class DataPuterAndGetter { 對象

//用戶放置數據的MAP

public static final Map<String, String> StrMap = new HashMap<String, String>();

//用於自增

public static final AtomicInteger atomicInteger = new AtomicInteger(0);

//鎖

public static final Object LOCKER = new Object();


/**

 * 一個線程來讀取MAP中的數據

 * */

static class DataGetter extends Thread {

private Object locker;

public DataGetter(Object locker) {

this.locker = locker;

}


@Override

public void run() {

while (true) {

synchronized (locker) {

if (StrMap.size() > 0) {

System.out.println(StrMap);

StrMap.clear();

try {

locker.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

 

} else {

try {

locker.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}


}

}

}

}

/**

 * 一個線程來把數據放置到MAP中

 * */

static class DataPutter extends Thread {


private AtomicInteger atomicInteger;

private Object locker;


public DataPutter(Object locker,AtomicInteger atomicInteger) {

this.locker = locker;

this.atomicInteger = atomicInteger;

}

public void run() {

while (true) {

synchronized (locker) {

int num = atomicInteger.addAndGet(1);

System.out.println("index is : ---->" + num);

StrMap.put("NUM_"+num, "index is :" + num);

locker.notify();

try {

Thread.sleep(100L);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

/**

 * 測試方法

 * */

public static void main(String args[]){

ExecutorService executorService = Executors.newCachedThreadPool();

executorService.execute(new DataPuterAndGetter.DataPutter(DataPuterAndGetter.LOCKER,DataPuterAndGetter.atomicInteger) );

executorService.execute(new DataPuterAndGetter.DataGetter(DataPuterAndGetter.LOCKER));

executorService.execute(new DataPuterAndGetter.DataGetter(DataPuterAndGetter.LOCKER));

}

}

以上程序用LOCKER來協調讀寫,可是synchronized 同一個LOCKER對應的內存塊,並無實現塞一個數據到MAP中,立刻從MAP中讀取一條數據出來。有點像MQ的味道了。

  

Blog提到了順序打印ABC,調試後能夠發現程序中處於wait狀態的線程,仍是須要修改下,也就是當程序結束時,調用LOCKERnotify方法。

整個測試程序以下:


package com.jdcloud.xue.gang.print;


public class Muti3Printer extends Thread {


private Object pre_LOCKER = new Object();

private Object self_LOCKER = new Object();

private Object next_LOCKER = new Object();


private String name;


public Muti3Printer(Object pre_LOCKER, Object self_LOCKER,

Object next_LOCKER, String name) {

super();

this.pre_LOCKER = pre_LOCKER;

this.self_LOCKER = self_LOCKER;

this.next_LOCKER = next_LOCKER;

this.name = name;

}


@Override

public void run() {

int count = 10;

while (count > 0) {

synchronized (pre_LOCKER) {

synchronized (self_LOCKER) {

System.out.print(name);

count--;

self_LOCKER.notify();

}

try {

pre_LOCKER.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

//程序結束後,解除全部的鎖

synchronized (pre_LOCKER){

pre_LOCKER.notify();

}

synchronized (self_LOCKER){

self_LOCKER.notify();

}

synchronized (next_LOCKER){

next_LOCKER.notify();

}


System.out.print("\n out -->" + name);

 

}


public static void main(String args[]) throws InterruptedException {


Object A_LOCKER = new Object();

Object B_LOCKER = new Object();

Object C_LOCKER = new Object();


Muti3Printer a_printer = new Muti3Printer(C_LOCKER, A_LOCKER, B_LOCKER,

"A");

Muti3Printer b_printer = new Muti3Printer(A_LOCKER, B_LOCKER, C_LOCKER,

"B");

Muti3Printer c_printer = new Muti3Printer(B_LOCKER, C_LOCKER, A_LOCKER,

"C");

a_printer.start();

Thread.sleep(100L);

b_printer.start();

Thread.sleep(100L);

c_printer.start();


}

}

相關文章
相關標籤/搜索