import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 一道经典的Java多线程编程题
* Created by yuanyong on 17/2/7.
* 问题描述
启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5,
然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15.
接着再由线程1打印16,17,18,19,20....以此类推,
直到打印到75. 程序的输出结果应该为:
*/
public class ThreadDemo2 {
final Lock lock = new ReentrantLock();
final Condition condition_1 = lock.newCondition();
final Condition condition_2 = lock.newCondition();
final Condition condition_3 = lock.newCondition();
public static volatile int number = 0;
class RunClass implements Runnable {
ConcurrentLinkedQueue<Integer> stack;
RunClass(Integer id, ConcurrentLinkedQueue<Integer> stack) {
this.id = id;
this.stack = stack;
}
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private void wirte() {
int i = 5;
while (i > 0) {
number++;
System.out.println(Thread.currentThread().getName() + ":" + number);
i--;
}
}
@Override
public void run() {
switch (id) {
case 1:
while (stack.size() > 0) {
//第一次
if (number == 0) {
lock.lock();
try {
wirte();
stack.poll();
condition_2.signal();
} finally {
lock.unlock();
}
} else {
lock.lock();
try {
condition_1.await();
if (stack.poll() == number) {
wirte();
condition_2.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
break;
case 2:
while (stack.size() > 0) {
lock.lock();
try {
condition_2.await();
if (stack.poll() == number) {
wirte();
condition_3.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
break;
case 3:
while (stack.size() > 0) {
lock.lock();
try {
condition_3.await();
if (stack.poll() == number) {
wirte();
condition_1.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
break;
}
}
}
public static void main(String args[]) {
ConcurrentLinkedQueue<Integer> stack1 = new ConcurrentLinkedQueue<Integer>();
ConcurrentLinkedQueue<Integer> stack2 = new ConcurrentLinkedQueue<Integer>();
ConcurrentLinkedQueue<Integer> stack3 = new ConcurrentLinkedQueue<Integer>();
ThreadDemo2 threadDemo2 = new ThreadDemo2();
RunClass runClass = threadDemo2.new RunClass(1, stack1);
RunClass runClass2 = threadDemo2.new RunClass(2, stack2);
RunClass runClass3 = threadDemo2.new RunClass(3, stack3);
Thread thread1 = new Thread(runClass, "线程1");
Thread thread2 = new Thread(runClass2, "线程2");
Thread thread3 = new Thread(runClass3, "线程3");
int n_1 = 0;
int n_2 = 5;
int n_3 = 10;
for (int n = 0; n < 5; n++) {
stack1.add(n_1);
stack2.add(n_2);
stack3.add(n_3);
n_1 += 15;
n_2 += 15;
n_3 += 15;
}
thread3.start();
thread2.start();
thread1.start();
}
}
实例2
线程屏障
CountDownLatch单词使用
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 一道经典的Java多线程编程题
* Created by yuanyong on 17/2/7.
* 问题描述
启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5,
然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15.
接着再由线程1打印16,17,18,19,20....以此类推,
直到打印到75. 程序的输出结果应该为:
*/
public class ThreadDemo2 {
ConcurrentLinkedQueue<Integer> stack1 = new ConcurrentLinkedQueue<Integer>();
ConcurrentLinkedQueue<Integer> stack2 = new ConcurrentLinkedQueue<Integer>();
ConcurrentLinkedQueue<Integer> stack3 = new ConcurrentLinkedQueue<Integer>();
final CountDownLatch startGate=new CountDownLatch(1);
// final CountDownLatch endGate=new CountDownLatch(3);
final Lock lock = new ReentrantLock();
final Condition condition_1 = lock.newCondition();
final Condition condition_2 = lock.newCondition();
final Condition condition_3 = lock.newCondition();
public static volatile int number = 0;
class RunClass2 implements Runnable{
public void run() {
//第一次
if (number == 0) {
lock.lock();
try {
wirte();
stack1.poll();
condition_2.signal();
} finally {
lock.unlock();
}
}
}
}
private void wirte() {
int i = 5;
while (i > 0) {
number++;
System.out.println(Thread.currentThread().getName() + ":" + number);
i--;
}
}
class RunClass implements Runnable {
ConcurrentLinkedQueue<Integer> stack;
RunClass(Integer id, ConcurrentLinkedQueue<Integer> stack) {
this.id = id;
this.stack = stack;
}
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public void run() {
// endGate.countDown();
// System.out.println(endGate.getCount());
try {
startGate.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("switch--------");
switch (id) {
case 1:
while (stack.size() > 0) {
lock.lock();
try {
condition_1.await();
if (stack.poll() == number) {
wirte();
condition_2.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
break;
case 2:
while (stack.size() > 0) {
lock.lock();
try {
condition_2.await();
if (stack.poll() == number) {
wirte();
condition_3.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
break;
case 3:
while (stack.size() > 0) {
lock.lock();
try {
condition_3.await();
if (stack.poll() == number) {
wirte();
condition_1.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
break;
}
}
public ConcurrentLinkedQueue<Integer> getStack() {
return stack;
}
public void setStack(ConcurrentLinkedQueue<Integer> stack) {
this.stack = stack;
}
}
public static void main(String args[]) throws BrokenBarrierException, InterruptedException {
ThreadDemo2 threadDemo2 = new ThreadDemo2();
RunClass runClass = threadDemo2.new RunClass(1, threadDemo2.stack1);
RunClass runClass2 = threadDemo2.new RunClass(2, threadDemo2.stack2);
RunClass runClass3 = threadDemo2.new RunClass(3, threadDemo2.stack3);
Thread thread1 = new Thread(runClass, "线程1");
Thread thread2 = new Thread(runClass2, "线程2");
Thread thread3 = new Thread(runClass3, "线程3");
int n_1 = 0;
int n_2 = 5;
int n_3 = 10;
for (int n = 0; n < 5; n++) {
threadDemo2.stack1.add(n_1);
threadDemo2.stack2.add(n_2);
threadDemo2.stack3.add(n_3);
n_1 += 15;
n_2 += 15;
n_3 += 15;
}
// threadDemo2.endGate.wait();
thread1.start();
thread2.start();
thread3.start();
Thread.sleep(3000);
threadDemo2.startGate.countDown();
new Thread(threadDemo2.new RunClass2()).start();
}
}
CyclicBarrier可以重复使用对应博文地址:
http://blog.youkuaiyun.com/shihuacai/article/details/8856407