zoukankan      html  css  js  c++  java
  • 用三个线程循环输出ABC

    前两天看Java吧有人求助这个问题。想了想并不是很难。今天就顺手实现了一下。

    我自己想到的有两种方法,一个是使用synchronized,一个是使用lock。

    一、synchronized

    package com.test;
    
    public class PrintABC {
        
        private static int count = 0;
    
        public static void main(String[] args) {
            String str = "ABC";
            PrintABC printABC = new PrintABC();
            ThreadA threadA = printABC.new ThreadA(str);
            ThreadB threadB = printABC.new ThreadB(str);
            ThreadC threadC = printABC.new ThreadC(str);
            threadA.start();
            threadB.start();
            threadC.start();
        }
        
        /**
         * 打印A
         * @author LKB
         *
         */
        class ThreadA extends Thread{
            
            private String str;
            
            public ThreadA(String str) {
                // TODO Auto-generated constructor stub
                this.str = str;
            }
            
            public void run(){
                while(count < 28){
                    synchronized (str) {
                        if(count%3 == 0){
                            System.out.println("A");
                            count++;
                        }
                    }
                }
            }       
        }
        
        /**
         * 打印B
         * @author LKB
         *
         */
        class ThreadB extends Thread{
            
            private String str;
            
            public ThreadB(String str) {
                // TODO Auto-generated constructor stub
                this.str = str;
            }
            
            public void run(){
                while(count < 29){
                    synchronized (str) {
                        if(count%3 == 1){
                            System.out.println("B");
                            count++;
                        }
                    }
                }
            }       
        }
        
        /**
         * 打印C
         * @author LKB
         *
         */
        class ThreadC extends Thread{
            
            private String str;
            
            public ThreadC(String str) {
                // TODO Auto-generated constructor stub
                this.str = str;
            }
            
            public void run(){
                while(count < 30){
                    synchronized (str) {
                        if(count%3 == 2){
                            System.out.println("C");
                            System.out.println("++++++");
                            System.out.println("------");
                            count++;
                        }
                    }
                }
            }       
        }
        
    
    }

    这个方法的关键是synchronized关键字的位置。把它放在while判断之下就OK了。如果把synchronized关键字放在while外,则一直在锁中无法跳出锁。

    二、lock

    package com.test;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class PrintABC2 {
        
        private int count = 0;
        private Lock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();
        
        public static void main(String[] args) {
            PrintABC2 printABC = new PrintABC2();
            ThreadA threadA = printABC.new ThreadA();
            ThreadB threadB = printABC.new ThreadB();
            ThreadC threadC = printABC.new ThreadC();
            threadA.start();
            threadB.start();
            threadC.start();
            
        }
        
        /**
         * 打印A
         * @author LKB
         *
         */
        class ThreadA extends Thread{
            
            public void run(){
                try {
                    lock.lock();
                    while(count < 30){
                        if (count%3 != 0) {
                            conditionA.await();
                        }
                        System.out.println("A");
                        count ++;
                        conditionB.signalAll();    
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                    System.out.println("ThreadA 中执行了 unlock");
                }
            }
        }
        
        /**
         * 打印B
         * @author LKB
         *
         */
        class ThreadB extends Thread{
            
            public void run(){
                try {
                    lock.lock();
                    while(count < 30){
                        if (count%3 != 1) {
                            conditionB.await();
                        }
                        System.out.println("B");
                        count ++;
                        conditionC.signalAll();                
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                    System.out.println("ThreadB 中执行了 unlock");
                }
            }
        }
        
        /**
         * 打印C
         * @author LKB
         *
         */
        class ThreadC extends Thread{
            
            public void run(){
                try {
                    lock.lock();
                    while(count < 30){
                        if (count%3 != 2) {
                            conditionC.await();
                        }
                        System.out.println("C");
                        System.out.println("+++++++");
                        System.out.println("-------");
                        count ++;
                        if(count < 30){
                            conditionA.signalAll();
                        }
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                    System.out.println("ThreadC 中执行了 unlock");
                }
            }
        }
        
    }

    lock方法相对而言就简单多了,不需要精妙地设计,只需要知道lock和condition的用法就好了。

    在一个lock对象里可以创建多个Condition(即对象监视器)实例。线程对象可以注册到指定的Condition中,从而可以有选择性地进行线程通知。

  • 相关阅读:
    Mybaits 源码解析 (十二)----- Mybatis的事务如何被Spring管理?Mybatis和Spring事务中用的Connection是同一个吗?
    Mybaits 源码解析 (十一)----- @MapperScan将Mapper接口生成代理注入到Spring-静态代理和动态代理结合使用
    Mybaits 源码解析 (十)----- Spring-Mybatis框架使用与源码解析
    Mybaits 源码解析 (九)----- 一级缓存和二级缓存源码分析
    Mybaits 源码解析 (八)----- 结果集 ResultSet 自动映射成实体类对象(上篇)
    Mybaits 源码解析 (七)----- Select 语句的执行过程分析(下篇)
    Mybaits 源码解析 (六)----- Select 语句的执行过程分析(上篇)
    Mybaits 源码解析 (五)----- Mapper接口底层原理(为什么Mapper不用写实现类就能访问到数据库?)
    Mybaits 源码解析 (四)----- SqlSession的创建过程
    Mybaits 源码解析 (三)----- Mapper映射的解析过程
  • 原文地址:https://www.cnblogs.com/cuglkb/p/7376026.html
Copyright © 2011-2022 走看看