美文网首页
Java ReentrantLock的使用demo:线程交替打印

Java ReentrantLock的使用demo:线程交替打印

作者: 小菜鸡 | 来源:发表于2020-09-24 10:18 被阅读0次

    笔/面试的时候常常遇到的一个问题,就是多个线程进行交替的打印任务:

    import java.util.concurrent.locks.ReentrantLock;
    
    public class PrintTask extends Thread {
        private String task;
        private Integer id;
        private static Integer taskId;
        private static Integer taskCount;
        private ReentrantLock lock;
    
        public PrintTask(String task, Integer id, Integer taskId, Integer taskCount, ReentrantLock lock) {
            this.task = task;
            this.setName("PrintTask-" + task);
            this.id = id;
            PrintTask.taskId = taskId;
            PrintTask.taskCount = taskCount;
            this.lock = lock;
        }
    
        @Override
        public void run() {
            while (true) {
                lock.lock();
                if (taskId % PrintTask.taskCount == id) {
                    System.out.println(task);
                    taskId = taskId == PrintTask.taskCount - 1 ? 0 : taskId + 1;
                }
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            String[] tasks = new String[]{"A", "B", "C"};
            //使用公平锁,当前线程打印完之后下一次不会马上又轮到自己去获取锁
            ReentrantLock lock = new ReentrantLock(true);
            PrintTask[] printTasks = new PrintTask[tasks.length];
            for (int i = 0; i < tasks.length; i++) {
                printTasks[i] = new PrintTask(tasks[i], i, 0, tasks.length, lock);
            }
            for (PrintTask printTask : printTasks) {
                printTask.start();
            }
        }
    }
    

    看一下运行结果:

    res.png
    没毛病,顺利输出了,然后再看看VisualVM:
    VM01.png
    虽然输出结果没问题,但是线程并没有严格的交替执行,是因为比如 Aunlock(),下次具体会是另外的那一个线程 ( B or C ) 获得锁还不一定。如果是 B 拿到了,就会如期的打印,但是如果是 C 拿到,又不打印,然后就会继续让出,而有可能又给了 AA 又会继续让出,直到 B 拿到并顺利打印。

    也就是说因该给每一个线程加一个条件标记,让每次当前的线程打印完毕之后,能够准确的指定让给下一个应该打印的线程。

    可以使用附随LockCondition来解决这个问题:

    相关文章

      网友评论

          本文标题:Java ReentrantLock的使用demo:线程交替打印

          本文链接:https://www.haomeiwen.com/subject/eikzyktx.html