n个线程交替打印26个字母

在学习多线程中看到有个题目:使用2个线程打印多个26个字母,看了网上的答案  基本都是使用wait和notify方法,对这个答案不是很满意,虽然功能是实现了 ,但是在扩展性方面有些差,所以在网上找资料 自己尝试着写了一个扩展性相对于 wait和notify 扩展性强一些的方式,在实际开发工作中可能不会用到

参考文章:https://blog.csdn.net/weixin_41826973/article/details/105501187

代码如下:

import java.util.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Function;

/***
 * n个线程交替打印26个字母
 */
public class TestPrintAlphabet {
    public static void main(String[] args) throws InterruptedException {
        LinkedList<String> list = new LinkedList<>(Arrays.asList("abcdefghijklmnopqrstuvwxyz".split("")));
        Function<T1, Boolean> isEnd = e -> list.size() > 0;
        Consumer<Object> operation = e -> {
            System.out.println(Thread.currentThread().getName() + " - " + list.removeFirst());
        };

        T1 t = new T1(operation, isEnd);
        Thread t1 = new Thread(t),
                t2 = new Thread(t),
                t3 = new Thread(t);
        t.initConditions(t1, t2, t3);
        t.notifyFirstCodition();
    }
}

class T1 implements Runnable {
    private Lock lock = new ReentrantLock();
    private Map<Thread, Integer> threadMap = new HashMap<>();
    // 线程对应的锁队列
    private List<Condition> conditions = new ArrayList<>();
    // 队列索引
    private volatile int conditionIndex = 1;
    // 结束条件
    private Function<T1, Boolean> isEnd;
    // 执行的操作
    private Consumer<Object> operation;

    public T1(Consumer<Object> operation, Function<T1, Boolean> isEnd){
        this.operation = operation;
        this.isEnd = isEnd;
    }

    @Override
    public void run() {
        Condition nowCondition;
        lock.lock();
        while (isEnd.apply(this)) {
            nowCondition = conditions.get(threadMap.get(Thread.currentThread()));
            try {
                nowCondition.await();
                if(!isEnd.apply(this)){
                    // 执行结束,唤起所有等待线程,结束运行
                    notifyAllCondition();
                    break;
                }
                operation.accept(this);
                notifyNextCondition();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        lock.unlock();
    }

    /***
     * 初始化线程列表
     * @param threads
     */
    public void initConditions(Thread... threads) {
        if(threads != null){
            Thread t;
            for(int i = 0; i < threads.length;i++){
                t = threads[i];
                threadMap.put(t, i);
                conditions.add(lock.newCondition());
                t.start();
            }
        }
    }

    /***
     * 唤醒第一个线程
     * @throws InterruptedException
     */
    public void notifyFirstCodition() throws InterruptedException {
        // 延迟执行,防止t1线程还没有尝试获取锁,主线程就唤醒t1线程,由于t1线程还没有获取到锁 所以唤起t1线程是不会生效的,主线程唤醒未获取锁的的t1线程后 t1线程无法被唤起 导致死锁
        Thread.sleep(1);
        if(conditions.size() > 0){
            lock.lock();
            conditions.get(0).signal();
            lock.unlock();
        }
    }

    /***
     * 唤醒下一个线程
     */
    public void notifyNextCondition(){
        if(conditionIndex >= conditions.size()){
            conditionIndex = 0;
        }
        conditions.get(conditionIndex).signal();
        conditionIndex++;
    }

    /***
     * 唤醒所有线程
     */
    public void notifyAllCondition(){
        lock.lock();
        for(Condition c : conditions){
            c.signal();
        }
        lock.unlock();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值