打赏

[******] 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();
    }
}

 

posted @ 2019-08-31 22:00  海米傻傻  阅读(716)  评论(0编辑  收藏  举报