项目12 12.3计时器线程_第1页
项目12 12.3计时器线程_第2页
项目12 12.3计时器线程_第3页
项目12 12.3计时器线程_第4页
项目12 12.3计时器线程_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java程序设计语言概述12.3计时器线程12.3计时器线程

在程序开发中,定时控制与周期性任务调度是常见需求,例如数据定时备份、界面动态刷新、服务状态监测等场景。Java通过计时器类(Timer)为开发者提供了灵活的任务调度能力,其核心功能围绕‌时间精准控制‌与‌异步任务执行‌展开,允许开发者设定单次执行、周期性执行或延迟触发的任务,从而简化复杂的时间管理逻辑。Java标准库中提供了两个功能定位迥异的Timer类,分别位于java.util和javax.swing包中,二者虽名称相同,但设计目标与适用场景存在本质差异。

而javax.swing.Timer则是专为‌图形界面交互‌设计的定时器。其核心逻辑与Swing事件分发线程(EventDispatchThread,EDT)深度绑定,确保所有任务在界面主线程中执行,避免多线程操作引发的界面冻结或控件状态冲突。例如,开发者可通过它实现实时时钟显示、动态进度条更新等。与java.util.Timer不同,其任务执行时间过长仅会导致界面短暂卡顿,而不会影响其他后台任务。此外,它提供setInitialDelay()和setDelay()方法灵活调整首次延迟与后续间隔,更适合需要与用户操作实时响应的场景。

位于java.util包的Timer是一个‌通用型后台任务调度器‌。它通过单线程(默认)管理任务队列,支持延迟启动、固定间隔执行(schedule())或严格时间计划执行(scheduleAtFixedRate())两种模式。例如,可以通过schedule()方法设定每天凌晨自动清理日志文件的任务,或在用户停止操作后延迟5秒触发草稿保存功能。然而,由于单线程模型的限制,若某个任务执行时间过长(如耗时计算或阻塞式IO操作),后续任务可能被延迟堆积,甚至因未捕获异常导致整个调度线程终止。因此,它更适用于轻量级后台任务,如资源维护、定时统计等场景。01java.util.Timer类01java.util.Timer类

java.util.Timer类与java.util.TimerTask类共同实现通用性后台任务调度。TimerTask是一个抽象类,表示要被定时执行的任务。它实现了Runnable接口,因此必须重写run方法来定义具体的任务逻辑。而Timer针对TimerTask实现延迟启动、固定间隔执行或严格时间计划执行。01java.util.Timer类

通过继承TimerTask类并重写run()方法定义具体的定时任务逻辑。该方法用于封装需要在预设时间触发的操作行为,例如数据清理、周期性状态检查或消息推送等业务动作。当任务到达调度计划中指定的触发时间时,Timer将自动调用该run()方法执行预定义的操作流程,从而实现“到期即执行”的精准控制。示例如下:publicclassMyTaskextendsTimerTask{@Overridepublicvoidrun(){try{System.out.println("定时任务执行:"+System.currentTimeMillis());

}catch(Exceptione){e.printStackTrace();}//在run()方法中捕获所有异常,否则会导致计时器线程终止}1.创建一个继承自TimerTask的类并重写run方法01java.util.Timer类初始化一个Timer对象,建议指定线程名称以便调试:Timertimer=newTimer("MyTimerThread");//后台线程自动启动MyTasktask=newMyTask();//常常和步骤一写成一体,特别是使用Lambda表达式2.创建Timer实例和TimerTask实例01java.util.Timer类可以根据需求选择以下三种调度方式:

延迟单次执行,任务在指定延迟后执行一次:timer.schedule(task,3000);//是3秒后执行

固定延迟重复执行‌,前次任务‌结束后‌,延迟固定时间再执行下一次:timer.schedule(task,1000,2000);//初始延迟1秒,之后每次间隔2秒

固定速率重复执行‌,严格按计划时间执行,若前次任务超时,后续任务会堆积:timer.scheduleAtFixedRate(task,1000,2000);//初始延迟1秒,之后每2秒执行一次(无视任务执行耗时)3.调度任务01java.util.Timer类

取消单个任务task.cancel();//标记任务为已取消,从队列中移除

终止整个计时器,停止所有任务并释放线程timer.cancel();//注意:若任务正在执行,会等待其完成java.util.Timer类完整实例如下:4.必要时取消任务importjava.util.Timer;importjava.util.TimerTask;/***火箭发射倒计时

🚀*每隔1秒打印倒计时,最后展示ASCII火箭动画*/publicclassRocketLaunch{publicstaticvoidmain(String[]args){Timertimer=newTimer();finalint[]countdown={5};//倒计时5秒TimerTasktask=newTimerTask(){@Overridepublicvoidrun(){if(countdown[0]>0){//打印动态倒计时

01java.util.Timer类4.必要时取消任务System.out.println("🕒"+countdown[0]+"→"+getFunnyMessage(countdown[0]));countdown[0]--;}else{//倒计时结束,发射火箭System.out.println("\n🚀

点火升空!");System.out.println("/\\\n"+"/\\\n"+"/____\\\n"+"|🚪|太空舱\n"+"|🔥|主发动机\n"+"╰┳-┳╯\n"+"🌍\n"+"地球越来越小了~");timer.cancel();//关闭计时器}}};//立即启动任务,每秒执行一次timer.scheduleAtFixedRate(task,0,1000);}//为倒计时添加幽默提示privatestaticStringgetFunnyMessage(intsecond){returnswitch(second){case5->"检查宇航员的咖啡是否喝完";case4->"确认火箭涂鸦已通过艺术审核";case3->"给外星人发送派对邀请函";case2->"最后一次检查WiFi信号";case1->"按下那个红色的大按钮!";default->"";};}}02javax.swing.Timer类02javax.swing.Timer类1.创建ActionListener实例,重写actionPerformed方法,定义定时任务的具体逻辑。ActionListenertask=newActionListener(){@OverridepublicvoidactionPerformed(ActionEvente){//定时执行的代码(例如更新界面组件)System.out.println("任务触发!当前时间:"+newDate());}};2.创建Timer实例,构造函数需指定延迟时间(毫秒)和事件监听器Timertimer=newTimer(delay,task);//delay是延迟时间(毫秒)02javax.swing.Timer类3.控制任务执行。

启动任务timer.start();//开始执行(首次触发在delay毫秒后)

停止任务timer.stop();//停止任务(可重新start()恢复)

单次执行模式timer.setRepeats(false);//关闭重复执行(只触发一次)timer.start();

动态调整触发间隔timer.setDelay(2000);//修改间隔为2秒(立即生效)

立即触发任务timer.setInitialDelay(0);//设置首次触发延迟为0毫秒

timer.start();//启动后立刻执行任务02javax.swing.Timer类javax.swing.Timer类完整实例如下importjavax.swing.*;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.util.Random;/***会跳舞的emoji笑脸

😄*在窗口里随机弹跳,碰撞边缘时变色*/publicclassBouncingSmile{publicstaticvoidmain(String[]args){JFrameframe=newJFrame("跳舞的笑脸");SmilePanelpanel=newSmilePanel();

frame.add(panel);frame.setSize(400,400);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);//创建Swing定时器(每50毫秒更新)newTimer(50,e->panel.move()).start();}}classSmilePanelextendsJPanel{privateintx=100,y=100;//初始位置privateintdx=3,dy=3;//移动速度privatefinalRandomrand=newRandom();privateColorcolor=Color.YELLOW;@OverrideprotectedvoidpaintComponent(Graphicsg){super.paintComponent(g);02javax.swing.Timer类javax.swing.Timer类完整实例如下//绘制变色笑脸g.setColor(color);g.fillOval(x,y,60,60);//脸g.setColor(Color.BLACK);g.fillOval(x+15,y+20,10,10);//左眼g.fillOval(x+35,y+20,10,10);//右眼g.drawArc(x+10,y+30,40,20,0,-180);//微笑的嘴}publicvoidmove(){//碰撞检测(窗口边缘)if(x<0||x>getWidth()-80){dx=-dx;color=newColor(rand.nextInt(256),rand.nextInt(256),rand.nextInt(256));}if(y<0||y>getHeight()-80){dy=-dy;color=newColor(rand.nextInt(256),rand.nextInt(256),rand.nextInt(256));}

x+=dx;//水平移动y+=dy;//垂直移动repaint();//触发重绘}}03项目演练03项目演练案例名称:龙舟竞渡协作模拟器(不完善,可运行)场景设定:

3支龙舟队(青龙/赤龙/金龙)协作竞速

每条龙舟对应独立线程(Thread类)

共享击鼓节奏资源(synchronized同步)

定时补充鼓点(java.util.Timer)

落后队伍请求支援(wait()/notify())

终点等待所有队伍(join())

完成时显示传统文化标语03项目演练案例名称:龙舟竞渡协作模拟器(不完善,可运行)‌文件资源DragonBoatRace/├─src/│

├─MainFrame.java//Swing界面│

├─BoatThread.java//龙舟线程│

├─DrumBeat.java//鼓点资源(synchronized)│

└─Achievement.java//成就提示操作过程:

1.代码编辑:使用记事本编辑代码,并保存2.编译‌:使用命令行界面编译代码,命令javacjavac-encodingUTF-8*.java3.执行代码:命令java主类名03项目演练‌1.主界面(Swing双线程)‌importjavax.swing.*;importjava.awt.*;importjava.util.Timer;importjava.util.TimerTask;publicclassMainFrameextendsJFrame{privatefinalDrumBeatdrum=newDrumBeat();privatefinalJTextArealogArea=newJTextArea();privatefinalJProgressBar[]bars=newJProgressBar[3];privatefinalString[]teams={"青龙队","赤龙队","金龙队"};publicMainFrame(){setTitle("端午龙舟竞渡v1.0");setSize(800,400);setLayout(newBorderLayout());

//进度条面板JPanelprogressPanel=newJPanel(newGridLayout(1,3));for(inti=0;i<3;i++){bars[i]=newJProgressBar(0,100);bars[i].setString(teams[i]);bars[i].setStringPainted(true);progressPanel.add(bars[i]);}

//日志面板JScrollPanelogScroll=newJScrollPane(logArea);logArea.setBackground(newColor(240,255,240));

add(progressPanel,BorderLayout.NORTH);add(logScroll,BorderLayout.CENTER);

startRace();}privatevoidstartRace(){//鼓点补给定时器(java.util.Timer)newTimer().scheduleAtFixedRate(newTimerTask(){publicvoidrun(){drum.addBeat();logAppend("[鼓声]咚!新的鼓点节奏到来!");}},3000,5000);//创建龙舟线程BoatThread[]boats={newBoatThread(teams[0],drum,this),newBoatThread(teams[1],drum,this),newBoatThread(teams[2],drum,this)};03项目演练//启动所有线程for(BoatThreadb:boats)b.start();//等待比赛结束(join)newThread(()->{try{for(BoatThreadb:boats)b.join();logAppend("\n======百舸争流千帆竞======");Achievement.showResult();}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}).start();}

//线程安全更新UIpublicvoidupdateProgress(Stringteam,intvalue){SwingUtilities.invokeLater(()->{for(inti=0;i<teams.length;i++){if(teams[i].equals(team)){bars[i].setValue(value);}}});}publicvoidlogAppend(Stringmsg){newjavax.swing.Timer(0,e->logArea.append(msg+"\n")).start();}publicstaticvoidmain(String[]args){SwingUtilities.invokeLater(()->newMainFrame().setVisible(true));}}03项目演练‌2.鼓点资源(synchronized同步)‌classDrumBeat{privateintbeats=3;//初始鼓点数量publicsynchronizedbooleangetBeat(Stringteam){while(beats<=0){try{wait();}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}beats--;returntrue;}publicsynchronizedvoidaddBeat(){beats+=2;notifyAll();}}‌3.龙舟线程(wait/notify)‌classBoatThreadextendsThread{privatefinalDrumBeatdrum;privatefinalMainFrameframe;privateintdistance;publicBoatThread(Stringname,DrumBeatdrum,MainFrameframe){super(name);this.drum=drum;this.frame=frame;}@Overridepublicvoidrun(){try{while(distance<100){//获取鼓点节奏drum.getBeat(getName());//前进逻辑distance+=(int)(Math.random()*10+5);frame.updateProgress(getName(),Math.min(distance,100));frame.logAppend(getName()+"前进至:"+dista

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论