首页 > 编程语言 >Java 多线程交替打印

Java 多线程交替打印

时间:2024-01-24 23:14:21浏览次数:30  
标签:Java int lock 打印 private print new 多线程 public

目录

题目

使用三个线程 T1、T2、T3,如何让他们按顺序交替打印 10 次 A B C。

方案一:synchronized

public class SynchronizedLockPrinter {
    static class Printer {
        private final Object lock = new Object();
        private static int count = 0;
        public void print(int n, int target, char content) {
            for (int i = 0; i < n; ) {
                synchronized (lock) {
                    while (count % 3 != target) {
                        try {
                            lock.wait();
                        } catch (Exception e) {
                            System.out.println(e);
                        }
                    }
                    System.out.print(content);
                    count++;
                    i++;
                    lock.notifyAll();
                }
            }
        }

        public void print() {
            new Thread(()-> {print(10, 0, 'A');}).start();
            new Thread(()-> {print(10, 1, 'B');}).start();
            new Thread(()-> {print(10, 2, 'C');}).start();
        }
    }

    public static void main(String [] args) {
        new Printer().print();
    }
}

方法二:ReentrantLock

public class SignalLockPrinter {
    static class Printer {
        private final Lock lock = new ReentrantLock();
        private static int count = 0;

        public void print(int n, int target, char content) {
            for (int i = 0; i < n; ) {
                lock.lock();
                try {
                    while (count % 3 == target) {
                        System.out.print(content);
                        count++;
                        i++;
                    }
                } catch (Exception e) {
                    System.out.println(e);
                } finally {
                    lock.unlock();
                }
            }
        }

        public void print() {
            new Thread(()-> {print(10, 0, 'A');}).start();
            new Thread(()-> {print(10, 1, 'B');}).start();
            new Thread(()-> {print(10, 2, 'C');}).start();
        }
    }

    public static void main(String [] args) {
        new Printer().print();
    }
}

方法三:ReentrantLock + Condition(非公平锁)

public class UnfairLockConditionPrinter {
    static class ConditionPrinter {
        private final Lock lock = new ReentrantLock(); // 非公平锁
        private static int count = 0;
        private final int threadNumber = 10;
        private final Condition condition1 = lock.newCondition();
        private final Condition condition2 = lock.newCondition();
        private final Condition condition3 = lock.newCondition();

        public void print(int target, String content, Condition current, Condition next) {
            for (int i = 0; i < threadNumber; i++) {
                lock.lock();
                try {
                    // 执行临界区代码前判断:防止锁被不满足条件的线程抢占
                    while (count % 3 != target) {
                        current.await(); // 条件等待并释放锁
                    }
                    System.out.print(content);
                    count++;
                    next.signal(); // 唤醒一个等待该条件的线程
                } catch (Exception e) {
                    System.out.println(e);
                } finally {
                    lock.unlock();
                }
            }
        }

        public void print() {
            new Thread(() -> {print(0, "A", condition1, condition2);}).start();
            new Thread(() -> {print(1, "B", condition2, condition3);}).start();
            new Thread(() -> {print(2, "C", condition3, condition1);}).start();
        }
    }

    public static void main(String[] args) {
        new ConditionPrinter().print();

    }
}

注意,unlock() 并不会阻塞当前线程,所以,当 A 线程在释放锁后,线程状态并没有改变,所以 A 线程还会去尝试获取一次锁,如果获取锁失败,就会进入阻塞状态;如果获取成功,就会进入条件等待状态。

优化:改成公平锁,可以减少锁的竞争程度。

方法四:ReentrantLock + Condition(公平锁)

public class FairLockConditionPrinter {
    static class ConditionPrinterEnhance {
        private final Lock lock = new ReentrantLock(true);
        private final Condition condition = lock.newCondition();
        private static int count = 0;
        private final int threadNumber = 10;
        public void print(int target, char content) {
            lock.lock();
            try {
                for (int i = 0; i < threadNumber; i++) {
                    while (count % 3 != target) {
                        condition.await();
                    }
                    System.out.println(Thread.currentThread().getName() + ": " + content + " " + count);
                    count++;
                    condition.signal();
                }
            } catch (Exception e) {
                System.out.println(e);
            } finally {
                lock.unlock();
            }
        }

        public void print() {
            char content = 'A';
            for (int i = 0; i < 3; i++) {
                final int k = i;
                new Thread(() -> print( k, (char) (content + k))).start();
            }
        }
    }

    public static void main(String[] args) {
        new ConditionPrinterEnhance().print();
    }
}

方法五:Semaphore

public class SemaphorePrinter {

    static class Printer {
        private final int n = 10;
        private final Semaphore s1 = new Semaphore(1);
        private final Semaphore s2 = new Semaphore(0);
        private final Semaphore s3 = new Semaphore(0);
        private void print(char content, Semaphore current, Semaphore next) {
            for (int i = 0; i < n; i++) {
                try {
                    current.acquire();
                    System.out.print(content);
                    next.release();
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }

        public void print() {
            new Thread(() -> {print('A', s1, s2);}).start();
            new Thread(() -> {print('B', s2, s3);}).start();
            new Thread(() -> {print('C', s3, s1);}).start();
        }
    }

    public static void main(String [] args) {
        new Printer().print();
    }
}

标签:Java,int,lock,打印,private,print,new,多线程,public
From: https://www.cnblogs.com/larry1024/p/17986059

相关文章

  • Java String
    String概览String被声明为final,因此它不可被继承。内部使用char数组存储数据,该数组被声明为final,这意味着value数组初始化之后就不能再引用其它数组。并且String内部没有改变value数组的方法,因此可以保证String不可变。publicfinalclassStringimplemen......
  • Java内存分配与回收策略
    HotSpot虚拟机GC分类针对HotSpot虚拟机的实现,GC可以分为2大类:部分收集(PartialGC)新生代收集(MinorGC/YoungGC):回收新生代,因为新生代对象存活时间很短,因此MinorGC会频繁执行,执行的速度一般也会比较快。老年代收集(MajorGC/OldGC):只对老年代进行垃圾收集。需......
  • java类文件结构
    类文件概述JVM可以理解的代码就叫做字节码(即扩展名为.class的文件,即类文件),它不面向任何特定的处理器,只面向虚拟机。Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。字节码并不针对一种特定的机器,因此Java......
  • java垃圾收集
    垃圾回收的脑图垃圾收集主要是针对堆和方法区进行。程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后就会消失,因此不需要对这三个区域进行垃圾回收。判断一个对象是否可被回收1.引用计数算法为对象添加一个引用计数器,当对象增......
  • Java学习日记 Day10
    Spring框给架:AOP:AOP切面编程一般可以帮助我们在不修改现有代码的情况下,对程序的功能进行拓展,往往用于实现日志处理,权限控制,性能检测,事务控制等。JDBCtemplate:我们做好配置文件以及加入依赖后可以通过JDBCtemplate技术来简化对数据库的操作。Spring事务:实现方式主要是注......
  • JAVA XStream简单使用
    XStreamxStream=newXStream(newStaxDriver());xStream.addPermission(AnyTypePermission.ANY);//不加后面转实体变异常xStream.processAnnotations(resultDTO.getClass());resultDTO=(ResultDTO)xStream.fromXML(result); 1、实体类设置别名  @XStreamAlias("Ma......
  • JavaScript ES6中 module , import和export
      假如你想直接在html的script里面使用import,你会遇到以下这两个问题:需要给script标签添加type='module'属性会遇到跨域问题,不单独启用一个服务器无法解决如果不启动一个server,访问js用的协议是file,不在浏览器跨域允许的协议中。因此无法做到拿到js文件,......
  • Java基础(一)
    文章目录第一章、java环境搭建1.1、Java介绍1.1.1、Java开发平台1.1.2、Java开发环境搭建1.1.3、Java专业术语1.1.4、第一个Java程序1.1.5、练习1.2、main方法1.3、变量1.3.1、变量介绍1.3.2、练习1.3.3、变量名规范1.3.4、注释1.4、数据类型......
  • 韩顺平java基础-13-常用类
    韩顺平java基础-13-常用类常用类包装类分类装箱和拆箱//自动装箱intn1=100;Integerinteger=intn1;//自动调用Integer.valueOf(n1)的方法//自动拆箱intn2=integer;//自动调用integer.intValue的方法包装类与String转换包装类型--->String类toString()......
  • 支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!
    1,最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败,则全部回滚。2,在spring中可以使用@Transactional注解去控制事务,使出现异常时会进行回滚,在多线程......