• 使用多线程循环交替打印字符


    使用Condition + Lock 进行实现

    private static int count_print = 1;

    (1)此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作
    (2)若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,因为三个线程,有三个线程实例即ThreadTest实例,若不设置成静态,
    那么每次改变的是对象内部的count_print属性,所以其他两个线程是不可见的



     程序一:

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ThreadTest implements Runnable {
    
        public static final int COUNT = 5;
        private final ReentrantLock reentrantLock;
        private final Condition thisCondition;
        private final Condition nextCondition;
        private final char printChar;
    
        // 此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作
        // 若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,因为三个线程,有三个线程实例即ThreadTest实例,若不设置成静态,
        // 那么每次改变的是对象内部的count_print属性,所以其他两个线程是不可见的
    
        private static int count_print = 1;
    
        public ThreadTest(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar) {
            this.reentrantLock = reentrantLock;
            this.thisCondition = thisCondition;
            this.nextCondition = nextCondition;
            this.printChar = printChar;
    
        }
    
        @Override
        public void run() {
            reentrantLock.lock();
    
            try {
                for (int i = 0; i < COUNT; i++) {
    
                    for (int j = 0; j < count_print; j++) {
                        System.out.print(printChar);
                    }
                    count_print += 1;
                    nextCondition.signal();
    
                    // 不是最后一次则通过thisCondtion等待被唤醒
                    // 必须要加判断,不然虽然能够打印5次,但5次后就会直接死锁
    
                    if (i < COUNT - 1) {
                        try {
                            // 使用Condition的await()方法将当前线程放入等待队列,并使其能在下一次被唤醒继续往下执行,而不是从头开始执行
                            thisCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } finally {
                reentrantLock.unlock();
            }
        }
    
        public static void main(String args[]) throws InterruptedException {
            ReentrantLock lock = new ReentrantLock();
            Condition conditionA = lock.newCondition();
            Condition conditionB = lock.newCondition();
            Condition conditionC = lock.newCondition();
    
            Thread threadA = new Thread(new ThreadTest(lock, conditionA, conditionB, 'A'));
            Thread threadB = new Thread(new ThreadTest(lock, conditionB, conditionC, 'B'));
            Thread threadC = new Thread(new ThreadTest(lock, conditionC, conditionA, 'C'));
    
            threadA.start();
            Thread.sleep(100);
            threadB.start();
            Thread.sleep(100);
            threadC.start();
        }
    }

    (1)//此处只能用static,来实现每打印一个字符,下一个字符长度加一,static是使该变量只有一个副本,任何改变都是对这个副本的内容做操作

    private static int count_print = 1;

    输出结果:

    (2)若是想实现每打印一组,下一组字符每个字符长度加一,就不使用static,因为三个线程,有三个线程实例即ThreadTest实例,若不设置成静态,
    那么每次改变的是对象内部的count_print属性,所以其他两个线程是不可见的,可能不太好理解,将ThreadTest类单独写出来,在利用import引入进另一个有主方法的类就比较直观了

    private int count_print = 1;

    输出结果:

     程序二

    //只是循环打印每组字符,不考虑字符增长
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ThreadTest implements Runnable {
    
        public static final int COUNT = 5;
        private final ReentrantLock reentrantLock;
        private final Condition thisCondition;
        private final Condition nextCondition;
        private final char printChar;
    
        private static int count_print = 1;
    
        public ThreadTest(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar) {
    
            this.reentrantLock = reentrantLock;
            this.thisCondition = thisCondition;
            this.nextCondition = nextCondition;
            this.printChar = printChar;
    
        }
    
        @Override
        public void run() {
            reentrantLock.lock();
    
            try {
                for (int i = 0; i < COUNT; i++) {
                    System.out.print(printChar);
                    nextCondition.signal();
                    if (i < COUNT - 1) {
                        try {
                            // 使用Condition的await()方法将当前线程放入等待队列,并使其能在下一次被唤醒继续往下执行,而不是从头开始执行
                            thisCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } finally {
                reentrantLock.unlock();
            }
        }
    
        public static void main(String args[]) throws InterruptedException {
            ReentrantLock lock = new ReentrantLock();
            Condition conditionA = lock.newCondition();
            Condition conditionB = lock.newCondition();
            Condition conditionC = lock.newCondition();
    
            Thread threadA = new Thread(new ThreadTest(lock, conditionA, conditionB, 'A'));
            Thread threadB = new Thread(new ThreadTest(lock, conditionB, conditionC, 'B'));
            Thread threadC = new Thread(new ThreadTest(lock, conditionC, conditionA, 'C'));
    
            threadA.start();
            Thread.sleep(100);
            threadB.start();
            Thread.sleep(100);
            threadC.start();
        }
    }

     运行结果为:

  • 相关阅读:
    MySQL和B树的那些事
    记一次临时抱佛脚的性能压测经历
    zookeeper api
    zookeeper笔记
    Mysql优化系列(1)--Innodb重要参数优化
    搞懂MySQL InnoDB B+树索引
    我以为我对Mysql索引很了解,直到我遇到了阿里的面试官
    HDFS原理概念扫盲
    设计原则
    设计模式 6大则
  • 原文地址:https://www.cnblogs.com/windy-xmwh/p/9176553.html
Copyright © 2020-2023  润新知