使用Java线程并发库实现两个线程交替打印的线程题
背景:是这样的今天在地铁上浏览了以下网页,看到网上一朋友问了一个多线程的问题。晚上闲着没事就决定把它实现出来。
题目:
1.开启两个线程,一个线程打印A~Z,两一个线程打印1~52的数据。
2.实现交替打印,输出结果为12A34B...........5152Z.
3.请用多线程方式实现。
这种只有两个线程交替打印数据的题目其实相对还是比较简单的,如果利用传统线程无非就是synchronized(线程互斥)与wait(),notify()的问题。
今天不用传统线程解决这个问题,我们用Java 1.5提供的线程并发库中的类来实现这个功能(实现流程和传统线程一样)
下面是实现代码(我都加了注释,如果还是不同大家可以查看Java 1.5以上的帮助文档)
package cn.yw.thread.practice; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 多线程练习: * 1.开启一个线程打印1~52,开启另一个线程打印A~Z * 打印方式:12A34B46C依次打印 * @author yw-tony * */ public class PracticeTest { public static void main(String[] args){ final DataPrint data = new DataPrint(); //打印字母的线程(大家也可以把这两个线程抽取出来作为两个单独的类,这里为了实现简单我就直接写在main方法中了) new Thread(new Runnable(){ @Override public void run() { while(data.letterFlag){ data.printLetter(); } } }).start(); //打印数字的线程 new Thread(new Runnable(){ @Override public void run() { while(data.numFlag){ data.printNun(); } } }).start(); } /** * 打印类 * @author yw-tony * */ static class DataPrint{ public boolean letterFlag = true;//线程结束标记; public boolean numFlag = true; //数字的初始值 int num = 1; //字母的初始值 //这里A~Z的字母对应的阿拉伯数字为65~90, int letter = 65; //线程等待标记 boolean flag = true; //java线程并发库中的锁相当与(synchronized) 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(); } } } }
分类:
Java
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
2013-01-05 Android 百度地图 在4.0以上系统上运行相当卡的问题