方法一
利用
Lock
锁中的Condition
等待/唤醒机制,让三个线程顺序打印1 ~ N
个数值。
public class ThreadQueueDemo {
static int count = 1;
static Lock lock = new ReentrantLock();
/**
* 定义每个线程对应的condition
*/
static Condition one = lock.newCondition();
static Condition two = lock.newCondition();
static Condition three = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new ThreadDemo(one,two),"thread-1");
Thread thread2 = new Thread(new ThreadDemo(two,three),"thread-2");
Thread thread3 = new Thread(new ThreadDemo(three,one),"thread-3");
thread1.start();
// 稍微等待下,以免线程乱序执行
Thread.sleep(100);
thread2.start();
Thread.sleep(100);
thread3.start();
}
private static class ThreadDemo implements Runnable{
// 当前线程锁通知条件
private Condition condition;
// 保存的下一个线程锁通知条件
private Condition nextCondition;
ThreadDemo(Condition condition,Condition nextCondition){
this.condition = condition;
this.nextCondition = nextCondition;
}
@Override
public void run() {
while (true){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+":"+count++);
try {
// 唤醒下一个线程
nextCondition.signal();
// 睡眠一下防止执行太快
Thread.sleep(500);
// 休眠当前线程
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}finally {
lock.unlock();
}
}
}
}
}
流程图大致流程
方法二
利用
队列(Queue)
、volatile
、LockSupport::park,LockSupport:unpark
实现。
public class QueueTest{
public static volatile int count = 1;
public static final int MAX_COUNT = 100;
public static final int MAX_THREAD_NUM = 3;
public static volatile boolean flag = true;
// 无界的队列,使用有界队列时需注意线程数要小于等于队列长度
public static final Queue queue = new LinkedBlockingQueue();
public static void main(String[] args){
// 循环增加线程到阻塞队列
for (int i = 1; i <= MAX_THREAD_NUM ; i++) {
queue.add(new Thread(()->{
while (true){
// 将当前线程追加到队列尾部
queue.add(Thread.currentThread());
System.out.println(Thread.currentThread().getName() + ":" + count++);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 让主线程中的循环得以继续
flag = true;
// 暂停当前线程
LockSupport.park(Thread.currentThread());
}
},"Thread-"+i));
}
while (count < MAX_COUNT){
// 利用volatile的可见性来保证线程执行的顺序性
if (flag) {
flag = false;
Thread thread;
// 取出队列中的线程来执行
if ((thread = (Thread) queue.poll()) != null) {
Thread.State state = thread.getState();
//如果为未启动状态,则先启动
if (state == Thread.State.NEW) {
thread.start();
// 如果为等待状态则解除等待
} else if (state == Thread.State.WAITING) {
LockSupport.unpark(thread);
}
}
}
}
// 中断线程,安全退出
Thread thread;
while ((thread = (Thread) queue.poll()) != null) {
thread.interrupt();
}
}
}
图片.png大致流程
能力有限,如有错误,欢迎指点。。。
网友评论