• [******] java多线程连续打印abc


    题目描述

    建立三个线程A、B、C,A线程打印10次字母A,B线程打印10次字母B,C线程打印10次字母C,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印。

    5种方法

    1. 使用synchronized, wait和notifyAll
    2. 使用Lock->ReentrantLock 和 state标志
    3. 使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)
    4. 使用Semaphore
    5. 使用AtomicInteger
    6. 扩展:采用join实现(一次性打印)

    5.1 使用synchronized, wait和notifyAll

    public class ABC7 {
        private static Object o = new Object();//所对象
        private static int state = 0;//控制顺序
        private static int PRINT_NUMBER = 10;//打印次数
        private static int THREAD_NUM = 3;//线程数量
        
        static class ThreadGenetic implements Runnable {
            char name;
            int data;
            public ThreadGenetic(char name, int data){
                this.name = name;
                this.data = data;
            }
            public void run() {
                synchronized (o) {
                    for(int i = 0; i < PRINT_NUMBER; ) {
                        if(state % THREAD_NUM == data){//保证顺序
                            System.out.print(name);
                            ++ state;
                            i++;//注意保证迭代次数
                            o.notifyAll();
                        }else{
                            try {
                                o.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    
        
        public static void main(String[] args) {
            new Thread(new ThreadGenetic('B',1)).start();
            new Thread(new ThreadGenetic('A',0)).start();
            new Thread(new ThreadGenetic('C',2)).start();
    
        }
    
    }


    5.2 使用Lock->ReentrantLock 和 state标志

    import java.util.concurrent.locks.ReentrantLock;
    
    public class ABC {
        private static int state = 0;//控制顺序
        private static int PRINT_NUMBER = 10;//打印次数
        private static int THREAD_NUM = 3;//线程数量
        private static ReentrantLock lock = new ReentrantLock();//
        
        static class ThreadGenetic extends Thread{
            char name;
            int data;
            public ThreadGenetic(char name, int data){
                this.name = name;
                this.data = data;
            }
            public void run(){
                for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
                    lock.lock();
                    if(state % THREAD_NUM == this.data){//确保按顺序打印
                        System.out.print(this.name);
                        state++;    //确保按顺序打印
                        i++;        //确保打印次数
                    }
                    lock.unlock();
                }
            }
        }
        
        public static void main(String[] args) {
            new ThreadGenetic('B',1).start();
            new ThreadGenetic('C',2).start();
            new ThreadGenetic('A',0).start();
        }
    }


    5.3 使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)

    方法1

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ABC8 {
        private static int state = 0;//控制顺序
        private static int PRINT_NUMBER = 10;//打印次数
        private static int THREAD_NUM = 3;//线程数量
        private static ReentrantLock lock = new ReentrantLock();//
        private static Condition condition = lock.newCondition();
        
        static class ThreadGenetic extends Thread{
            char name;
            int data;
            public ThreadGenetic(char name, int data){
                this.name = name;
                this.data = data;
            }
            public void run(){
                lock.lock();
                try {
                    for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
                        while(state % THREAD_NUM != data){//确保按顺序打印
                            condition.await();
                        }
                        System.out.print(name);
                        state++;    //确保按顺序打印
                        i++;        //确保打印次数
                        condition.signalAll();
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                lock.unlock();
            }
        }
        
        public static void main(String[] args) {
            new ThreadGenetic('B',1).start();
            new ThreadGenetic('C',2).start();
            new ThreadGenetic('A',0).start();
        }
    }

    方法2

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ABC2 {
        private static int state = 0;//控制顺序
        private static int PRINT_NUMBER = 10;//打印次数
        private static int THREAD_NUM = 3;//线程数量
        private static ReentrantLock lock = new ReentrantLock();//
        private static Condition conditionA = lock.newCondition();
        private static Condition conditionB = lock.newCondition();
        private static Condition conditionC = lock.newCondition();
        
        static class ThreadGenetic extends Thread{
            char name;
            int data;
            Condition condition1;
            Condition condition2;
            public ThreadGenetic(char name, int data, Condition condition1,Condition condition2){
                this.name = name;
                this.data = data;
                this.condition1 = condition1;
                this.condition2 = condition2;
            }
            public void run(){
                lock.lock();
                try {
                    for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
                        while(state % THREAD_NUM != data){//确保按顺序打印
                            condition1.await();
                        }
                        System.out.print(name);
                        state++;    //确保按顺序打印
                        i++;        //确保打印次数
                        condition2.signal();
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                lock.unlock();
            }
        }
        
        public static void main(String[] args) {
            new ThreadGenetic('B',1,conditionB,conditionC).start();
            new ThreadGenetic('C',2,conditionC,conditionA).start();
            new ThreadGenetic('A',0,conditionA,conditionB).start();
        }
    }

    5.4 使用Semaphore

    import java.util.concurrent.Semaphore;
    
    public class ABC3 {
        private static int PRINT_NUMBER = 10;//打印次数
        private static Semaphore semaphoreA = new Semaphore(1);
        private static Semaphore semaphoreB = new Semaphore(1);
        private static Semaphore semaphoreC = new Semaphore(1);
        
        static class ThreadGenetic extends Thread{
            char name;
            int data;
            Semaphore semaphore1;
            Semaphore semaphore2;
            public ThreadGenetic(char name, Semaphore semaphore1,Semaphore semaphore2){
                this.name = name;
                this.semaphore1 = semaphore1;
                this.semaphore2 = semaphore2;
            }
            public void run(){
                for (int i = 0; i < PRINT_NUMBER; i++) {//确保打印次数
                    try {
                        semaphore1.acquire();
                        System.out.print(name);
                        semaphore2.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                }
            }
        }
        public static void main(String[] args) {
            try {
                semaphoreB.acquire();//保证A先于BC开始
                semaphoreC.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new ThreadGenetic('B',semaphoreB,semaphoreC).start();
            new ThreadGenetic('C',semaphoreC,semaphoreA).start();
            new ThreadGenetic('A',semaphoreA,semaphoreB).start();
        }
    }

    5.5 使用AtomicInteger

    import java.util.concurrent.atomic.AtomicInteger;
    
    public class ABC5 {   
        private static AtomicInteger atomicinteger = new AtomicInteger(0);
        private static final int MAX_SYC_VALUE = 3 * 10;
    
        static class ThreadGenetic extends Thread {
            char name;
            int data;
    
            public ThreadGenetic(char name, int data) {
                this.name = name;
                this.data = data;
            }
            
            public void run() {
                while (atomicinteger.get() < MAX_SYC_VALUE-1) {
                    if (atomicinteger.get() % 3 == data) {
                        System.out.print(name);
                        atomicinteger.getAndIncrement();
                    }
                }
    
            }
        }
    
        public static void main(String[] args) {
            new ThreadGenetic('B', 1).start();
            new ThreadGenetic('C', 2).start();
            new ThreadGenetic('A', 0).start();
        }
    }

    5.6 采用join实现(一次性打印)

    public class ABC6 {
    
        public static void main(String[] args) {
            // 线程A
            final Thread a = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("A");
                }
            });
    
            // 线程B
            final Thread b = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 执行b线程之前,加入a线程,让a线程执行
                        a.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("B");
                }
            });
    
            // 线程C
            final Thread c = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 执行c线程之前,加入b线程,让b线程执行
                        b.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("C");
                }
            });
    
            // 启动三个线程
            a.start();
            b.start();
            c.start();
        }
    }
  • 相关阅读:
    正则表达式
    匿名函数作业
    内置函数&匿名函数
    模拟面试题一
    迭代器
    生成器
    装饰器
    函数
    疑问?
    3,app信息抽取
  • 原文地址:https://www.cnblogs.com/haimishasha/p/11440686.html
Copyright © 2020-2023  润新知