您好,欢迎来到花图问答。
搜索
您的当前位置:首页多线程中交替执行任务

多线程中交替执行任务

来源:花图问答

最近一直在公司对使用storm来统计相关数据时,发现需要使用到高并发的知识,基于之前对高并发相关知识没有系统的学习,现在慢慢研究和学习。

在解决两个线程相互交替执行任务时,我们用到了重入锁ReentrantLock,又叫做递归锁。重入锁指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响,其实ReentrantLock和synchronized都是可重入锁。

public boolean letterFlag = true;//线程结束标记;
public boolean numFlag = true;

//数字的初始值
int num = 1;
//字母的初始值
//这里A~Z的字母对应的阿拉伯数字为65~90,
int letter = 65;
//线程等待标记
boolean flag = true;

Lock lock = new ReentrantLock();
//线程并发库中用于线程之间通讯的类相当于wait(),notify()
Condition condLetter = lock.newCondition();
Condition condNum = lock.newCondition();

public void printLetter(){
    //如果打印到Z则结束线程并停止
    if(letter >= 90 ){
        letterFlag = false;
        return ;
    }
    //锁定代码块,锁定时其他线程不能访问其中内容
    lock.lock();
    try{
        if(flag){//如果执行打印数字的线程正在执行,则该线程进入等待状态
            condLetter.await();
        }
        System.out.println(Thread.currentThread().getName()+":"+(char)letter);
        letter++;
        Thread.sleep(100);
        //打印执行完成,唤醒打印数字的线程
        flag = true;
        condNum.signal();
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //解锁当前代码快
        lock.unlock();
    }
}

public void printNun(){
    //如果打印到52则结束线程并停止
    if(num>=52){
        numFlag = false;
        return;
    }
    lock.lock();
    try{
        if(!flag){
            condNum.await();
        }
        System.out.println(Thread.currentThread().getName()+":"+num);
        num++;
        System.out.println(Thread.currentThread().getName()+":"+num);
        num++;
        Thread.sleep(100);
        flag = false;
        condLetter.signal();//唤醒打印字母的线程
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        lock.unlock();
    }
}

我们可以看到使用flag进行状态变化的标识,以及用到了锁的工作:
Condition condLetter = lock.newCondition();
Condition condNum = lock.newCondition();
上面两个锁对象就是针对写字母和写数字模块的控制写入顺序,这样就会就可以产生交替变换写数据

Copyright © 2019- huatuowenda.com 版权所有 湘ICP备2023022495号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务