22.线程通信Condition
Condition
通过此对象可以与lock实现组合使用,为每个对象提供多个等待,实现多个阻塞队列。
package dmeo9;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class DemoLock2 {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
public void m1(){
try {
lock.lock();
System.err.println(Thread.currentThread().getName()+":线程,进入m1");
Thread.sleep(3000);
System.err.println(Thread.currentThread().getName()+":线程,释放锁,接收通唤醒知");
condition1.await();
System.err.println(Thread.currentThread().getName()+":线程,继续执行 m1");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void m2(){
try {
lock.lock();
System.err.println(Thread.currentThread().getName()+":线程,进入m2");
Thread.sleep(3000);
System.err.println(Thread.currentThread().getName()+":线程,发出通知,唤醒");
condition1.signal();
System.err.println(Thread.currentThread().getName()+":线程,继续执行 m2");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public static void main(String[] atgs) {
final DemoLock2 demoLock = new DemoLock2();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
demoLock.m1();;
}
},"消费者t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
demoLock.m2();;
}
},"生产者t2");
t1.start();
t2.start();
}
}
输出:
消费者t1:线程,进入m1 消费者t1:线程,释放锁,接收通唤醒知 生产者t2:线程,进入m2 生产者t2:线程,发出通知,唤醒 生产者t2:线程,继续执行 m2 消费者t1:线程,继续执行 m1
多Condition组合
package dmeo9;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by liudan on 2017/8/4.
*/
public class DemoLock3 {
/**
* 通过一对象产生lock对象,并生产多个Condition进行多线程的交互,可以做到一部分唤醒,另一部分继续等待。
*/
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
public void m1() {
try {
lock.lock();
System.err.println(Thread.currentThread().getName() + ":进入m1");
Thread.sleep(100);
System.err.println(Thread.currentThread().getName() + ":m1释放锁,接收通唤醒知");
condition1.await();
System.err.println(Thread.currentThread().getName() + ":继续执行 m1");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void m2() {
try {
lock.lock();
System.err.println(Thread.currentThread().getName() + ":进入m2");
Thread.sleep(200);
System.err.println(Thread.currentThread().getName() + ":m2释放锁,接收通唤醒知");
condition1.await();
System.err.println(Thread.currentThread().getName() + ":继续执行 m2");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void m3() {
try {
lock.lock();
System.err.println(Thread.currentThread().getName() + ":进入m3");
Thread.sleep(300);
System.err.println(Thread.currentThread().getName() + ":m3释放锁,接收通唤醒知");
condition2.await();
System.err.println(Thread.currentThread().getName() + ":继续执行 m3");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void m4() {
try {
lock.lock();
System.err.println(Thread.currentThread().getName() + ":进入m4");
Thread.sleep(400);
System.err.println(Thread.currentThread().getName() + ":m4发出通知并唤醒:m1、m2");
condition1.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void m5() {
try {
lock.lock();
System.err.println(Thread.currentThread().getName() + ":进入m5");
Thread.sleep(500);
System.err.println(Thread.currentThread().getName() + ":m5发出通知并唤醒:m3");
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] atgs) {
DemoLock3 demoLock3 = new DemoLock3();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
demoLock3.m1();
}
}, "_1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
demoLock3.m2();
}
}, "_2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
demoLock3.m3();
}
}, "_3");
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
demoLock3.m4();
}
}, "_4");
Thread t5 = new Thread(new Runnable() {
@Override
public void run() {
demoLock3.m5();
}
}, "_5");
t1.start();
t2.start();
t3.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t4.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t5.start();
- }
}
输出:
_1:进入m1 _1:m1释放锁,接收通唤醒知 _2:进入m2 _2:m2释放锁,接收通唤醒知 _3:进入m3 _3:m3释放锁,接收通唤醒知 _4:进入m4 _4:m4发出通知并唤醒:m1、m2 _1:继续执行 m1 _2:继续执行 m2 _5:进入m5 _5:m5发出通知并唤醒:m3 _3:继续执行 m3
常用方法
* 公平锁、非公平锁
* Lock lock = new ReentrantLock(boolean isFair)。
* tryLock()尝试去获取锁,并获得结果用false、true返回,并在给定的时间内去获取。
* isFair():是否公平锁。
* isLocked():是否锁定
* getHoldCount():查询当前的线程保存的锁存在的个数,也就是调用lock的次数。
* lockinterruptibly():优先响应中断的锁。
* getQueueLength():返回正在等待获取此锁的线程数量。
* getWaitQueueLenth():获取返回等待与锁定相关的给定条件condition的线程数量。
* hasQueuedThread(Thread thread):查询指定的线程是否正在等待此锁。
* hasQueuedThread():查询是否有线程正在等待次锁。
* hasWaiters():查询是否有线程正在等待与此锁有关的condition条件。