首先在使用Lock来保证线程同步时,需使用Condition对象来使线程保持协调。Condition实例被绑定在一个Lock的对象上,使用Lock对象的方法newCondition()获取Condition的实例。Condition提供了下面三种方法,来协调不同线程的同步:
1、await():导致当前线程等待,直到其他线程调用该Condition的signal()或signalAll()方法唤醒该线程。
2、signal():唤醒在此Lock对象上等待的单个线程。
3、signalAll():唤醒在此Lock对象上等待的所有线程。
class Share2{
private int num1 = 0;
private Lock lock1 = new ReentrantLock();
private Condition condition = lock1.newCondition();
public void incr() throws InterruptedException {
lock1.lock();
try {
while(num1 != 0) {
condition.await();
}
num1++;
System.out.println(Thread.currentThread().getName()+"::"+num1);
condition.notifyAll();
}catch (Exception e) {
e.printStackTrace();
}finally {
lock1.unlock();
}
}
public void desc() throws InterruptedException {
lock1.lock();
try {
while(num1 != 1) {
condition.await();
}
num1--;
System.out.println(Thread.currentThread().getName()+"::"+num1);
condition.notifyAll();
}catch (Exception e) {
e.printStackTrace();
}finally {
lock1.unlock();
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Share2 s2 = new Share2();
new Thread(()->{
for (int i = 0; i <= 30; i++) {
try {
s2.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A线程").start();
new Thread(()->{
for (int i = 0; i <= 30; i++) {
try {
s2.desc();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B线程").start();
new Thread(()->{
for (int i = 0; i <= 30; i++) {
try {
s2.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C线程").start();
new Thread(()->{
for (int i = 0; i <= 30; i++) {
try {
s2.desc();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D线程").start();
}
}
Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。阻塞队列实际上是使用了Condition来模拟线程间协作。
Conditon中的await()对应Object的wait();
Condition中的signal()对应Object的notify();
Condition中的signalAll()对应Object的notifyAll()。