一、java的notify与wait
package org.calonlan.soulpower;
public class MyThreadTest implements Runnable {
private String name;
private Object prev;
private Object self;
public MyThreadTest(String name, Object prev, Object self) {
super();
this.name = name;
this.prev = prev;
this.self = self;
}
@Override
public void run() {
int count = 10;
while (count > 0) {
synchronized (prev) {//请求获得上一个的锁
synchronized (self) {//请求获得自己的锁
System.out.println(name+"--"+count);
count--;
try {
Thread.sleep(1);//这里测试sleep,sleep只会让当前线程让出cpu、内存等资源,但不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
self.notify();//通知等待sefl的锁的线程可以启动了,同时在synchronized (self)块执行完成后释放self锁,程序继续执行
}
try {
prev.wait();//这里释放prev锁,并且程序进入阻塞状态。等在notify的时候重新启动程序执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception {
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThreadTest ta = new MyThreadTest("A", c, a);
MyThreadTest tb = new MyThreadTest("B", a, b);
MyThreadTest tc = new MyThreadTest("C", b, c);
new Thread(ta).start();
Thread.sleep(10);//---------{
new Thread(tb).start();// |
Thread.sleep(10);//---------{三个Thread.sleep()是让主线程中保证三个线程按顺序启动
new Thread(tc).start();// |
Thread.sleep(10);//---------{
}
}
package org.calonlan.soulpower;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBufferTest {
final Lock lock = new ReentrantLock();//定义一个锁
final Condition notFull = lock.newCondition();//锁中的状态,用来标识notfull
final Condition notEmpty = lock.newCondition();//锁中的状态,用来标识notempty
final Object[] items = new Object[100];//队列
int putptr, takeptr, count;
public void put(Object x) throws Exception {
lock.lock();
/*在lock与unlock之间的代码才能保证线程安全*/
try {
// condition需要在while中判断
while (count == items.length)
notFull.await();//队列满的了时候用notFull来阻塞程序
/*接收到notFull的signal或者队列本来就不满执行下面的代码*/
items[putptr] = x;
if (++putptr == items.length)
putptr = 0;
++count;
notEmpty.signal();
} finally {
/*在lock与unlock之间的代码才能保证线程安全*/
lock.unlock();
}
}
public Object take() throws Exception {
lock.lock();
/*在lock与unlock之间的代码才能保证线程安全*/
try {
while (count == 0)
notEmpty.await();//使用notemty来阻塞线程(如果count==0的时候),这里一定要用while来做判断
Object x = items[takeptr];
if (++takeptr == items.length)
takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
/*在lock与unlock之间的代码才能保证线程安全*/
lock.unlock();
}
}
static class Thread1 extends Thread {
private BoundedBufferTest BoundedBufferTest;
public Thread1(BoundedBufferTest boundedBufferTest) {
super();
BoundedBufferTest = boundedBufferTest;
}
@Override
public void run() {
int count = 0;
try {
while (true) {
System.out.println(count + "放入");
BoundedBufferTest.put(count++);
Thread.sleep(100);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
static class Thread2 extends Thread {
private BoundedBufferTest BoundedBufferTest;
public Thread2(BoundedBufferTest boundedBufferTest) {
super();
BoundedBufferTest = boundedBufferTest;
}
@Override
public void run() {
try {
while (true) {
System.out.println(Thread.currentThread().getName()
+ BoundedBufferTest.take());
Thread.sleep(10000);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
BoundedBufferTest boundedBufferTest = new BoundedBufferTest();
Thread2 thread2 = new Thread2(boundedBufferTest);
Thread1 thread1 = new Thread1(boundedBufferTest);
thread1.start();
thread2.start();
}
}