Java实现多线程循环输出abc

本文介绍了两种在Java中实现多线程循环输出abc的方法。一种是结合synchronized关键字和volatile修饰符,保证线程顺序执行;另一种是利用Semaphore信号量控制线程执行顺序,实现循环打印。两种方法都确保了线程间的同步和数据的一致性。
摘要由CSDN通过智能技术生成

使用synchronized和volatile来实现

通过在关键代码块或方法前添加synchronized关键字,可以确保同一时间只有一个线程能够执行该代码块或方法。

使用volatile修饰符,以确保修饰的字段在不同线程之间的可见性,它是被多个线程共享的。

工作原理

在上述示例中,printLetter()方法被声明为synchronized,这意味着同一时间只有一个线程能够执行这个方法。每个线程在执行printLetter()方法之前都会检查currentThread的值是否等于自己的threadId,如果不等于,则进入等待状态,直到其他线程执行完毕并释放锁。

当某个线程的threadId与currentThread相同时,线程可以执行打印操作,并将currentThread更新为下一个线程的threadId,然后唤醒所有等待的线程。

通过这种方式,每个线程按照指定的顺序获取锁并执行打印操作,从而实现了线程的顺序执行。

需要注意的是,我们在currentThread字段前面使用了volatile修饰符,以确保不同线程之间的可见性,这是因为该字段会被多个线程共享。

具体代码

public class ABCPrinter {
    private volatile int currentThread = 0;

    public synchronized void printLetter(String letter, int threadId){
        while (threadId != currentThread) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(letter);
        currentThread = (currentThread + 1) % 3;
        notifyAll();
    }

    public static void main(String[] args) {
        ABCPrinter printer = new ABCPrinter();

        Thread threadA = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printer.printLetter("a", 0);
            }
        });

        Thread threadB = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printer.printLetter("b", 1);
            }
        });

        Thread threadC = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printer.printLetter("c", 2);
            }
        });

        threadA.start();
        threadB.start();
        threadC.start();
    }
}

使用信号量来实现

当需要按照指定的顺序执行多线程任务时,可以使用一些同步机制来实现。在这种情况下,可以考虑使用Java中的信号量Semaphore)来控制线程的执行顺序。

工作原理

在上述示例中,使用三个信号量semaphoreA,semaphoreB和semaphoreC来控制线程的执行顺序。

初始时,semaphoreA可用,而semaphoreB和semaphoreC不可用。printA()方法首先获取semaphoreA的许可,打印字符"a",然后释放semaphoreB的许可,使得printB()方法可以执行。

类似地,printB()方法获取semaphoreB的许可,打印字符"b",然后释放semaphoreC的许可,使得printC()方法可以执行。printC()方法获取semaphoreC的许可,打印字符"c",然后释放semaphoreA的许可,使得printA()方法可以再次执行,从而实现了循环的输出"abc"。

具体代码

import java.util.concurrent.Semaphore;

public class ABCPrinter {
    private Semaphore semaphoreA;
    private Semaphore semaphoreB;
    private Semaphore semaphoreC;

    public ABCPrinter(){
        semaphoreA = new Semaphore(1);
        semaphoreB = new Semaphore(0);
        semaphoreC = new Semaphore(0);
    }

    public void printA(){
        try{
            semaphoreA.acquire();
            System.out.println("a");
            semaphoreB.release();
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    public void printB(){
        try{
            semaphoreB.acquire();
            System.out.println("b");
            semaphoreC.release();
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    public void printC(){
        try{
            semaphoreC.acquire();
            System.out.println("c");
            semaphoreA.release();
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ABCPrinter printer = new ABCPrinter();

        Thread threadA = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printer.printA();
            }
        });

        Thread threadB = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printer.printB();
            }
        });

        Thread threadC = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printer.printC();
            }
        });

        threadA.start();
        threadB.start();
        threadC.start();
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多线程每个线程挨着打印abc的4种实现方式如下: 1. 使用同步方法: 在一个类中创建一个共享的锁对象。创建3个线程,分别调用该对象的3个同步方法,在每个方法中使用循环打印对应的字符,然后调用notifyAll()方法唤醒其他两个线程,最后调用wait()方法当前线程进入等待状态。 2. 使用synchronized关键字: 在一个类中创建一个共享的锁对象,并使用synchronized关键字修饰方法。创建3个线程,分别调用该对象的3个同步方法,在每个方法中使用循环打印对应的字符,然后调用notifyAll()方法唤醒其他两个线程,最后调用wait()方法当前线程进入等待状态。 3. 使用Lock和Condition接口: 创建一个ReentrantLock对象和3个Condition对象。创建3个线程,分别获取对应的Condition对象,然后在循环中使用Lock对象的lock()方法获取锁,使用对应的Condition对象的await()方法等待,直到该线程被唤醒后打印对应的字符,并调用其他两个Condition对象的signalAll()方法唤醒其他两个线程。 4. 使用信号量Semaphore: 创建一个Semaphore对象和3个线程。在每个线程中使用Semaphore对象的acquire()方法获取许可,然后在循环打印对应的字符,最后调用Semaphore对象的release()方法释放许可,并通知其他两个线程获取许可。 以上这四种方式都可以实现多线程每个线程挨着打印abc的效果。然而,具体的选择取决于实际情况,例如需要考虑线程的数量、同步机制的复杂度、线程间协作的方式等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值