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

Posted haimishasha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[******] 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();
    

 

以上是关于[******] java多线程连续打印abc的主要内容,如果未能解决你的问题,请参考以下文章

java多线程连续打印字母数字问题

多线程常见手撕问题

Java多线程通信之两个线程分别打印AB各10次

java多线程 线程八锁

JAVA多线程编程,创建3个线程分别打印A,B和C,打印10次

Java多线程循环打印ABC的5种实现方法