您的位置:首页 > 大数据 > 人工智能

多线程中wait、notify理解

2015-09-17 20:57 344 查看
实在惭愧,java开发多年,多线程运用一直不多,该知识点理解也不够,不怎么会用。赶上使用多线程 生产者、消费者模式,学习下该知识点。

synchronized 获取锁

wait 阻塞本线程,释放对象锁。该线程会在该代码处阻塞,不往下执行。

notify 释放对象锁,通知其他被阻塞的线程可以被唤醒。

Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

IllegalMonitorStateException异常发生是由于程序员没有注意notify(),notify(),wait()方法的使用条件,没有真正理解线程同步机制。如果当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。个人暂时理解为若线程没有持有任何锁,而调用这几个方法,会出现该异常。

package socket;

public class Producer2 extends Thread {

public class Producer extends Thread {

private Share shared;
private int   number;

public Producer(Share s, int number) {
shared = s;
this.number = number;
}

public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("[00]");
shared.put(i);
System.out.println("生产者" + this.number + " 输出的数据为:" + i);
try {
sleep((int) (Math.random() * 100));//这里一定要加,否则(注释掉sleep代码)消费者可能会暂时取不到cpu控制权,而没办法打印出信息。而此时消费者get()方法中已经执行notify方法,导致生产者被唤醒,继续生产执行put(),给人误导没有消费。实际已经消费而只是未打印而已。
} catch (InterruptedException e) {
}
System.out.println("[000]");
}
}
}

// 共享资源对象

public class Share {

private int     contents;
private boolean available = false;

public synchronized int get() {
System.out.println("[1]");
if (available == false) {
try {
System.out.println("[2]");
wait();
System.out.println("[3]");
} catch (InterruptedException e) {
}
}
available = false;
System.out.println("[4]");
notify();// 通知其他使用该对象的线程,你们可以在适当的时间被唤醒了。只要我锁一释放(synchronized方法体执行完),其他线程就有被唤醒的可能,就有可能把锁抢过去执行了。
System.out.println("[5]");
return contents;
}

public synchronized void put(int value) {
System.out.println("[6]");
if (available == true) {
try {
System.out.println("[7]");
wait();// 我不使用该对象了,本线程睡觉了,现在是其他对象被唤醒的时机,你们可以在被wait的地方继续执行了
System.out.println("[8]");
} catch (InterruptedException e) {
}
}
available = true;
System.out.println("[9]");
notify();//这里也要加,原因是,用于唤醒其他线程,不加的话,在本线程睡觉后,消费者线程不被唤醒,生产者线程唤醒其他线程的notify方法没有机会执行,那生产者线程会一直睡大觉了。
System.out.println("[10]");
contents = value;
}
}

// 消费者程序

public class Consumer extends Thread {

private Share shared;
private int   number;

public Consumer(Share s, int number) {
shared = s;
this.number = number;
}

public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
System.out.println("[11]");
value = shared.get();
System.out.println("消费者" + this.number + " 得到的数据为:" + value);
}
}
}

// 主程序

public static void main(String[] args) {
Producer2 test = new Producer2();
Share s = test.new Share();
Producer p = test.new Producer(s, 1);
Consumer c = test.new Consumer(s, 1);
p.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c.start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: