package com.thread_test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by zhen on 2017-06-06.
*/
public class ConditionTest {
/**
* Condition 的功能类似在传统线程技术中的Object.wait和Object.notify的功能。在等待Condition时,允许发生“虚拟唤醒”,
* 这通常作为普通平台语义的让步。
* condition的await方法与signal方法类似于Object的wait和notify方法
* 如果只是这样,那么Condition的出现有什么意义呢?
*
*/
public static void main(String[] args){
final Business business = new Business();
new Thread(new Runnable(){
public void run() {
for(int i = 1; i <= 50; i++){
business.sub1(i);
}
}
}).start();
new Thread(new Runnable(){
public void run() {
for(int i = 1; i <= 50; i++){
business.sub2(i);
}
}
}).start();
for(int i = 1; i <= 50; i++){
business.main(i);
}
}
static class Business{
private static int runSeq = 0;
private Lock lock = new ReentrantLock();
private Condition main = lock.newCondition();
private Condition sub1 = lock.newCondition();
private Condition sub2 = lock.newCondition();
public void main(int i){
lock.lock();
while(runSeq != 0){
try {
main.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try{
System.out.println("main thread run time is " + i);
for(int j = 1; j <= 100; j++){
System.out.println("main thread out " + j);
}
runSeq = 1;
sub1.signal();
}finally{
lock.unlock();
}
}
public void sub1(int i) {
lock.lock();
try {
while (runSeq != 1) {
try {
sub1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("sub1 thread run time is " + i);
for (int j = 1; j <= 10; j++) {
System.out.println("sub1 thread out " + j);
}
runSeq = 2;
sub2.signal();
} finally {
lock.unlock();
}
}
public void sub2(int i){
lock.lock();
try{
while(runSeq != 2){
try {
sub2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("sub2 thread run time is " + i);
for(int j = 1; j <= 10; j++){
System.out.println("sub2 thread out " + j);
}
runSeq = 0;
main.signal();
}finally{
lock.unlock();
}
}
/**
* 缓冲队列问题
* 需求:呼机的中转机器,接受话务员的输入指令,使用发布机向外界发布消息信号,发布机各种限制下只能每秒1条发布,所以需要一个缓冲队列
* 分析:
* 队列的实现使用数组
* 多线程。多个线程进行写入,1个线程进行发布。
* 写入的顺序从0到数组长度,到底了从0又开始循环。如果下一个位置已经有元素了,等待,通知发布。
* 发布也是从0开始到数组长度,到底了又开始循环。如果下一个位置没有元素了,等待,通知写入。
*
* Condition可以存在多个。
*
*/
class BoundBuffer{
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try{
while(count == items.length){
notFull.await();
}
items[putptr] = x;
if(++putptr == items.length){
putptr = 0;
}
++count;
notEmpty.signal();
}finally{
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try{
while(count == 0){
notEmpty.await();
}
Object x = items[takeptr];
if(++takeptr == items.length){
takeptr = 0;
}
-- count;
notFull.signal();
return x;
}finally {
lock.unlock();
}
}
}
}
}