java线程交替执行的实现

目录

方式1:使用synchronized+wait/notify实现

方式2:使用 Lock+Condition实现

方式3:通过 LockSupport实现

方式4:线程池+LockSupport


         这是个老生常谈的问题了,但里面涵盖的知识还是有必要好好琢磨一下子。这里简单总结了一下,写了个多个线程交替打印1-100的例子,实现如下;

方式1:使用synchronized+wait/notify实现

@Slf4j
public class ThreadDemo3 {
    public static void main(String[] args) {
        RunnableImpl runnable = new RunnableImpl(100,1);

        String [] threadNames = new String[]{"A","B","C","D"};

        List<Thread> threadList = new ArrayList<Thread>();
        for (int i = 0; i < threadNames.length; i++) {
            threadList.add(new Thread(runnable,threadNames[i]));
        }
        runnable.setThreadList(threadList);
        for (int i = 0; i < threadList.size(); i++) {
            threadList.get(i).start();
        }
    }


    private static class RunnableImpl implements Runnable{
        private int count;
        private int index;
        private List<Thread> threadList;
        private Object lock = new Object();

        public RunnableImpl(int count ,int index){
            this.index = index;
            this.count = count;
        }

        private void setThreadList(List<Thread> threadList){
            this.threadList = threadList;
        }

        @Override
        public void run() {
            while(index < count){
                synchronized (lock){
                    if(Thread.currentThread().getName().equals("A") ){
                        while(index % 4 != 1){
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                break;
                            }
                        }
                    }else if(Thread.currentThread().getName().equals("B") ){
                        while(index % 4 != 2){
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                break;
                            }
                        }
                    }else if(Thread.currentThread().getName().equals("C") ){
                        while(index % 4 != 3){
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                break;
                            }
                        }
                    }else if(Thread.currentThread().getName().equals("D") ){
                        while(index % 4 != 0){
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                break;
                            }
                        }
                    }
                    if(index > count){
                        this.interrupt();
                        break;
                    }
                    log.info("{} ---->{}",Thread.currentThread().getName(),index);
                    index++;
                    lock.notifyAll();
                }
            }

        }

        private void interrupt() {
            for (int i = 0; i < threadList.size(); i++) {
                threadList.get(i).interrupt();
            }
        }
    }
}

方式2:使用 Lock+Condition实现

@Slf4j
public class ThreadDemo4 {
    public static void main(String[] args) {
        Runnable runnable = new RunnableImpl(100,1);
        String [] threadNames = new String[]{"A","B","C"};
        List<Thread> threadList = new ArrayList<Thread>();
        for (int i = 0; i < threadNames.length; i++) {
            threadList.add(new Thread(runnable,threadNames[i]));
        }
        for (int i = 0; i < threadList.size(); i++) {
            threadList.get(i).start();
        }
    }
    private static class RunnableImpl implements Runnable{
        private int count;
        private int index;
        private Lock lock = new ReentrantLock();
        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        public RunnableImpl(int count ,int index){
            this.index = index;
            this.count = count;
        }

        @Override
        public void run() {
            while(index < count){
                lock.lock();
                try{
                    if(Thread.currentThread().getName().equals("A") ){

                        while(index % 3 != 1 ){
                            conditionA.await();
                        }
                        conditionB.signal();
                    }else if(Thread.currentThread().getName().equals("B") ){
                        while(index % 3 != 2 ){
                            conditionB.await();
                        }
                        conditionC.signal();
                    }else if(Thread.currentThread().getName().equals("C") ){
                        while(index % 3 != 0 ){
                            conditionC.await();
                        }
                        conditionA.signal();
                    }
                    if(index > count){
                        break;
                    }
                    log.info("{} ---->>{}",Thread.currentThread().getName(),index);
                    index++;
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }

        }
    }
}

方式3:通过 LockSupport实现

@Slf4j
public class ThreadDemo5 {
    public static void main(String[] args) {
        String threadNames[] = new String[]{"A","B","C"};

        int index = 1;
        int count = 100;

        List<Thread> threadList = new ArrayList<Thread>();
        RunnableImpl runnable = new RunnableImpl(index,count,threadList);

        for (int i = 0; i < threadNames.length; i++) {
            threadList.add(new Thread(runnable,threadNames[i]));
        }

        for (int i = 0; i < threadList.size(); i++) {
            threadList.get(i).start();
        }
    }

    private static class RunnableImpl implements Runnable{

        private int index;
        private int count;
        private List<Thread> threads;
        public RunnableImpl(int index, int count,List<Thread> threads){
            this.index = index;
            this.count = count;
            this.threads = threads;
        }

        @Override
        public void run() {
            while(index <= count){
                String threadName = Thread.currentThread().getName();
                if(threadName.equals("A")){
                    if((index % (threads.size())) !=1){
                        LockSupport.park();
                    }else{
                        log.info(Thread.currentThread().getName()+" --->"+index);
                        index++;
                        LockSupport.unpark(threads.get(1));
                    }

                }else if(threadName.equals("B")){
                    if((index % (threads.size() )) != 2){
                        LockSupport.park();

                    }else{
                        log.info(Thread.currentThread().getName()+" --->"+index);
                        index++;
                        LockSupport.unpark(threads.get(2));
                    }

                }else if(threadName.equals("C")){
                    if((index % (threads.size() ) )!=0){
                        LockSupport.park();

                    }else{
                        log.info(Thread.currentThread().getName()+" --->"+index);
                        index++;
                        LockSupport.unpark(threads.get(0));
                    }
                }
                if(index>count){
                    LockSupport.unpark(threads.get(0));
                    LockSupport.unpark(threads.get(1));
                    LockSupport.unpark(threads.get(2));
                }
            }
        }
    }
}

方式4:线程池+LockSupport

@Slf4j
public class ThreadDemo8 {
    public static void main(String[] args) throws InterruptedException {
        String[] threadNames = new String[]{"A", "B", "C"};

        ThreadFactoryImpl threadFactory = new ThreadFactoryImpl(threadNames, threadNames.length);
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 3,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(),
                threadFactory);
        int[] integer = {1};
        while(integer[0] <100){
            poolExecutor.execute(() -> {
                if(integer[0] >100){
                    LockSupport.unpark(threadFactory.getThread("A"));
                    LockSupport.unpark(threadFactory.getThread("B"));
                    LockSupport.unpark(threadFactory.getThread("C"));
                    return;
                }
                if (Thread.currentThread().getName().equals("A")) {
                    if (integer[0] % 3 != 1) {
                        LockSupport.park();
                    } else {
                        log.info("{} --->> {}", Thread.currentThread().getName(), integer[0]);
                        integer[0]++;
                        LockSupport.unpark(threadFactory.getThread("B"));
                    }
                } else if (Thread.currentThread().getName().equals("B")) {
                    if (integer[0] % 3 != 2) {
                        LockSupport.park();
                    } else {
                        log.info("{} --->> {}", Thread.currentThread().getName(), integer[0]);
                        integer[0]++;
                        LockSupport.unpark(threadFactory.getThread("C"));
                    }
                } else if (Thread.currentThread().getName().equals("C")) {
                    if (integer[0] % 3 != 0) {
                        LockSupport.park();
                    } else {
                        log.info("{} --->> {}", Thread.currentThread().getName(), integer[0]);
                        integer[0]++;
                        LockSupport.unpark(threadFactory.getThread("A"));
                    }
                }

            });
        }

        poolExecutor.shutdown();

    }

    private static class ThreadFactoryImpl implements ThreadFactory {

        private int index;
        private String[] threadNames;
        private Thread[] threads;

        public ThreadFactoryImpl(String[] threadNames, int index) {
            this.threadNames = threadNames;
            threads = new Thread[threadNames.length];
        }

        public Thread getThread(String threadName) {
            for (int i = 0; i < threads.length; i++) {
                if (threads[i].getName().equals(threadName)) {
                    return threads[i];
                }
            }
            return null;
        }

        @Override
        public Thread newThread(Runnable r) {
            if (index < threadNames.length) {
                threads[index] = new Thread(r, threadNames[index]);
            }
            return threads[index++ % threadNames.length];
        }
    }
}

总结


        实力源于基础,Java高并发的任务分片依赖于多线程,对于这个知识点还需深入理解一下。我这里简单改写了一下方式1的写法,也可以了解一下,代码中有写的不到位的地方请在留言中指出;

@Slf4j
public class ThreadDemo6 {
    public static void main(String[] args) {
        String[] threadNames = new String[]{"A","B","C","D","E","F","G","H"};
        List<Thread> threadList = new ArrayList<>();
        RunnableImpl runnable = new RunnableImpl(100,1,threadNames);
        for (int i = 0; i < threadNames.length; i++) {
            Thread thread =new Thread(runnable,threadNames[i]);
            threadList.add(thread);
        }
        runnable.setThreadList(threadList);
        for (int i = 0; i < threadList.size(); i++) {
            threadList.get(i).start();
        }
    }


    private static class RunnableImpl implements Runnable{
        private int count;
        private int index;
        private String[] threadNames;
        private Object lock = new Object();
        private List<Thread> threadList;

        public RunnableImpl(int count ,int index,String[] threadNames){
            this.index = index;
            this.count = count;
            this.threadNames = threadNames;
        }
        
        public void setThreadList(List<Thread> threadList){
            this.threadList = threadList;
        }

        @Override
        public void run() {

            while(index < count){
                synchronized (lock){
                    String name = Thread.currentThread().getName();
                    for (int i = 0; i < threadNames.length; i++) {
                        if(name.equals(threadNames[i]) ){
                            while(index % threadNames.length != (i+1) % threadNames.length ){
                                try {
                                    lock.wait();
                                } catch (InterruptedException e) {
                                    break;
                                }
                            }
                        }
                    }
                    if(index > count){
                       this.interrupt();
                       break;
                    }
                    log.info("{} ---->> {}",name ,index);
                    index++;
                    lock.notifyAll();
                }
            }

        }
        public void interrupt(){

            for (int i = 0; i < threadList.size(); i++) {
                threadList.get(i).interrupt();
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值