目录
- 背景介绍
 - 实现方式
 - 总结提升
 
 
背景介绍
  有一个需求是要求多个线程去执行任务,需要每个线程都执行一次之后再继续执行,也就是说每个线程交替去执行任务。举个例子来说,有两个线程,一个输出字母,一个输出数字。交替输出1A2B3C4D5E…来实现这样一个业务场景。

实现方式
- 使用LockSupport类中的unpark方法和park方法。unpark方法用来叫醒指定的线程,park方法用来将当前队列进入到阻塞的状态。
 
package com.example.threadpool.LockSupport;
import java.util.concurrent.locks.LockSupport;
/**
 * @BelongsProject: demo
 * @BelongsPackage: com.example.threadpool.LockSupport
 * @Author: Wuzilong
 * @Description: 使用LockSupport类中的park和unpark方法实现线程交替执行
 * @CreateTime: 2023-11-11 10:07
 * @Version: 1.0
 */
public class AlternatingExecution {
    private static Thread t1;
    private static Thread t2;
    public static void main(String[] args) {
        char[] oneArray="1234567".toCharArray();
        char[] twoArray="ABCDEFG".toCharArray();
         t1=new Thread(() ->{
            for (char one : oneArray){
                System.out.print(one);
                LockSupport.unpark(t2);//叫醒t2线程
                LockSupport.park();//阻塞当前线程
            }
        },"t1");
         t2 = new Thread(() ->{
            for (char two: twoArray){
                LockSupport.park();
                System.out.print(two);
                LockSupport.unpark(t1);
            }
        },"t2");
         t1.start();
         t2.start();
    }
}运行结果

- 使用synchronized锁和notify方法和wait方法实现线程交替执行,notify方法事用来唤醒线程,wait方法是将当前的线程放到等待队列中等待执行,不允许执行其他的动作。
 
package com.example.threadpool.sync_notify_wait;
/**
 * @BelongsProject: demo
 * @BelongsPackage: com.example.threadpool.sync_notify_wait
 * @Author: Wuzilong
 * @Description: 使用synchronized锁住o对象,然后使用notify唤醒线程和wait去让线程等待
 * @CreateTime: 2023-11-11 14:25
 * @Version: 1.0
 */
public class Client {
    public static void main(String[] args) {
        Object o = new Object();
        char[] oneArray="123456".toCharArray();
        char[] twoArray="ABCDEF".toCharArray();
        new Thread(()->{
            synchronized (o){
                for (char one:oneArray){
                    System.out.print(one);
                    try{
                        o.notify();//唤醒线程
                        o.wait();//将线程放到等待队列中等待执行,不允许执行其他的动作
                    }catch ( Exception e){
                        e.printStackTrace();
                    }
                }
                o.notify();//必须添加,否则无法停止程序
            }
        },"t1").start();
        new Thread(()->{
            synchronized (o){
                for(char two:twoArray){
                    System.out.print(two);
                    try{
                        o.notify();
                        o.wait();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        },"t2").start();
    }
}运行结果

- 使用Lock锁和condition的signal方法和await方法实现多线程之间交替执行,signal方法用来唤醒其他线程,await方法用来将当前线程进入阻塞队列。
 
package com.example.threadpool.lock_condition;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * @BelongsProject: demo
 * @BelongsPackage: com.example.threadpool.lock_condition
 * @Author: Wuzilong
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-11-11 15:39
 * @Version: 1.0
 */
public class Client {
    public static void main(String[] args) {
        char oneArray[]="123456".toCharArray();
        char twoArray[]="ABCDEF".toCharArray();
        Lock lock=new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(()->{
            lock.lock();
            try{
                for (char one: oneArray){
                    System.out.println(one);
                    condition.signal();  //唤醒其他线程
                    condition.await(); //当前线程进入阻塞队列
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        },"t1").start();
        new Thread(()->{
            lock.lock();
            try{
                for (char two:twoArray){
                    System.out.println(two);
                    condition.signal();
                    condition.await();
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        },"t2").start();
    }
}运行结果

- 使用LinkedTransferQueue队列中的take方法和transfer方法实现多个线程交替执行,transfer方法是向队列中添加内容,添加的内容如果没有被使用是不会执行下面的代码逻辑的,take方法是从队列中获取内容。
 
package com.example.threadpool.TransferQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
/**
 * @BelongsProject: demo
 * @BelongsPackage: com.example.threadpool.TransferQueue
 * @Author: Wuzilong
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-11-11 16:39
 * @Version: 1.0
 */
public class Client {
    public static void main(String[] args) {
        char[] oneArray="123456".toCharArray();
        char[] twoArray="ABCDEF".toCharArray();
        //声明一个队列
        TransferQueue<Character> queue=new LinkedTransferQueue<>();
        new Thread(()->{
            try{
                for (char one:oneArray){
                    System.out.print(queue.take()); //从队列中获取内容
                    queue.transfer(one);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        },"t1").start();
        new Thread(()->{
            try{
                for(char two :twoArray){
                    queue.transfer(two); //向队列中添加内容,添加的内容如果没有被拿走是不会执行下面的代码逻辑的。
                    System.out.print(queue.take());
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        },"t2").start();
    }
}运行效果

总结提升
对于一个需求的实现方式有很多种,我们可以通过不同的维度,针对于业务的侧重点不同来由不同的实现方式,我们要有无限的思想去思考问题,要有发展的眼光去看待问题。
 
此文章对你有用的话记得留言+点赞+收藏哦🎯 
  
 
                










