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

原文地址:https://www.cnblogs.com/haimishasha/p/11440686.html

时间: 2024-10-12 05:41:42

[******] java多线程连续打印abc的相关文章

java多线程打印ABC

/** * 方案一 * * @author LY */ public class LockObject { public String lockName; public LockObject() { } public LockObject(String lockName) { this.lockName = lockName; } public String getLockName() { return lockName; } public void setLockName(String loc

(转载)Java多线程入门理解

转载出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalan

转:关于JAVA多线程同步

转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖于若干方法和关键字.将心得记录如下: 1  wait方法:        该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所在的代码块的锁,并在其他线程调用notify或者notifyAll方法时恢复到竞争锁状态

Java多线程学习

写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线

Java多线程学习(吐血超具体总结)

林炳文Evankaka原创作品. 转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文仅仅能说是java多线程的一个入门.事实上Java里头线程全然能够写一本书了,可是假设最基本的你都学掌握好,又怎么能更上一个台阶呢?假设你认为此文非常简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 文件夹(?)[-] 一扩展ja

[转] Java多线程发展简史

这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从第一个版本开始,在多线程编程方面的大事件和发展脉络有一个描述,并且提及一些在多线程编程方面常见的问 题.对于Java程序员来说,如果从历史的角度去了解一门语言一个特性的演进,或许能有不同收获. 引言 首先问这样一个问题,如果提到Java多线程编程,你会想到什么? ● volatile.synchronized关键字? ● 竞争和同步? ● 锁机制? ● 线程安全

Java 多线程IO简单实用Demo

多线程主要作用是充分利用Cpu,而不在于它的乱序性.本Demo不讲它竞争什么的.之前看过乱序打印ABC的例子什么的,那些有意义吗? 本Demo 是多线程打印文件夹下的文件,主要实现是用数组存放文件,一个游标遍历. 我们需要考虑在什么时候加互斥访问,本例用synchronized . 先考虑单线程的流程:客户端启动-->读取文件下的文件放到数组(IO)--> 取游标打印 ,游标加1 -- > 改文件写文件(IO) -- 重复上两步至越界 -- 结束 多线程时显然需要在"取游标打印

***Java多线程发展简史

http://blog.jobbole.com/28297/ 本文来自四火的博客(@RayChase),由@_Zhijun 推荐 这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从第一个版本开始,在多线程编程方面的大事件和发展脉络有一个描述,并且提及一些在多线程编程方面常见的问题.对于Java程序员来说,如果从历史的角度去了解一门语言一个特性的演进,或许能有不同收获. 引言 首先问这样一个问题,如果提到Java

Java多线程总结(转载)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是Java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalan