zoukankan      html  css  js  c++  java
  • 使用多线程循环交替打印字符

    使用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();
        }
    }

     运行结果为:

  • 相关阅读:
    python学习笔记番外:linux文件拷贝程序
    好看视频爬虫2.0
    Serverless 如何在阿里巴巴实现规模化落地?
    开放下载!2021 解锁 Serverless 从入门到实战大“橙”就
    这位硬核程序员,想好怎么过春节了吗?
    mysql error 1130 hy000:Host 'localhost' is not allowed to connect to this mysql server 解决方案
    DockerFile
    一种移动端的token设计方案(适合app+h5)
    elk7.5搭建详解
    关于rabbitmq与kafka的异同
  • 原文地址:https://www.cnblogs.com/windy-xmwh/p/9176553.html
Copyright © 2011-2022 走看看