面试题分享---多线程的顺序执行与循环执行

最近在网上看到一篇关于多线程的面试题,平时虽然有看过一些并发的理论,但是实际编码较少,因此也是特意练习一下。

题目描述:

怎么让线程A、线程B、线程C顺序执行?

方案一:利用线程的join()方法,join()方法是线程类的实例方法,其作用是在当前线程中调用目标线程的join()方法,则当前线程进入Waiting状态,目标线程执行完毕后当前线程才再次进入Runable状态。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new ThreadA());
        Thread t2 = new Thread(new ThreadB(t1));
        Thread t3 = new Thread(new ThreadC(t2));

        t1.start();
        t2.start();
        t3.start();
    }

    static class ThreadA implements Runnable {
        @Override
        public void run() {
            System.out.println("ThreadA");
        }
    }

    static class ThreadB implements Runnable{

        private Thread thread;

        public ThreadB(Thread thread) {
            this.thread = thread;
        }
        @Override
        public void run() {
            try {
                //目标线程先执行完才继续执行此线程执行体
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadB");
        }
    }

    static class ThreadC implements Runnable {

        private Thread thread;

        public ThreadC(Thread thread) {
            this.thread = thread;
        }
        @Override
        public void run() {
            try {
                //目标线程先执行完才继续执行此线程执行体
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadC");
        }
    }

}

方案二:借助线程池技术,newSingleThreadExecutor保证了其内只有一个线程在执行,且提交的线程执行体是按照FIFO的顺序执行的。

public class ExecutorServiceDemo {

    public static void main(String[] args) {
        ExecutorService executorPool = Executors.newSingleThreadExecutor();
        executorPool.submit(new ThreadA());
        executorPool.submit(new ThreadB());
        executorPool.submit(new ThreadC());
    }

    static class ThreadA implements Runnable {
        @Override
        public void run() {
            System.out.println("ThreadA");
        }
    }

    static class ThreadB implements Runnable{
        @Override
        public void run() {
            System.out.println("ThreadB");
        }
    }

    static class ThreadC implements Runnable {
        @Override
        public void run() {
            System.out.println("ThreadC");
        }
    }

}

怎么保证多个线程按顺序循环执行一段代码?

借鉴网上一种优雅的解决方案,但是原文的代码我认为有点问题,因为它对线程内部的代码加锁对于其他线程来说是无效的。
原文链接:https://blog.csdn.net/feng15230805625/article/details/83350724

但是其思路是可以借鉴的,它利用锁机制来实现对一个共享变量的互斥访问,然后当这个共享变量等于特定值时执行特定的线程。下面是我的代码:
对于add()方法,同一时间只能有一个线程执行它,然后在其内部持有一个计数器count,每次执行add()方法后修改计数器保证下一个线程执行add()方法。

public class CycleDemo {

    private static Integer count = 0;

    private synchronized static void add() {
        System.out.println(Thread.currentThread().getName());
        count++;

    }

    private static Integer get() {
        return count;
    }

    static class ThreadA implements Runnable {

        @Override
        public void run() {
            Thread.currentThread().setName("ThreadA");
            while (true) {
                if(get() % 3 == 0 && get() < 999) {
                    add(); //它保证了线程B在其后执行
                }
            }
        }
    }

    static class ThreadB implements Runnable {
        @Override
        public void run() {
            Thread.currentThread().setName("ThreadB");
            while (true) {
                if(get() % 3 == 1 && get() < 999) {
                    add();
                }
            }
        }
    }

    static class ThreadC implements Runnable {
        @Override
        public void run() {
            Thread.currentThread().setName("ThreadC");
            while (true) {
                if(get() % 3 == 2 && get() < 999) {
                    add();
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadA());
        Thread t2 = new Thread(new ThreadB());
        Thread t3 = new Thread(new ThreadC());
        t3.start();
        t2.start();
        t1.start();
        
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章