java 线程 每隔1小时执行一次_Java设计三个线程的睡眠,分别每隔1秒,5秒,10秒运行一次...

本文展示了如何在Java中创建三个线程,分别以1秒、5秒和10秒的周期运行。每个线程在运行时会显示其运行次数,并通过`sleep()`方法控制执行间隔。代码包括一个`Sleep`线程类和一个测试类`Sleep_test`,用户可以输入信号来结束各个线程的运行,并在所有线程结束后输出各自的运行时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编写三个线程分别显示各自的运行时间,第一个线程每隔1秒钟运行一次,第二个线程每隔5秒钟运行一次,第三个线程每隔10秒钟运行一次。

源代码

线程类Sleep类

package experiment.exp8;

public class Sleep extends Thread{

public int SleepTime=0;

public long time=0;

public int i=0;

public int k=1;

public Sleep(String s) {

super(s);

}

public synchronized void run()

{

long start=System.currentTimeMillis();

while(i==0)

{

System.out.println(Thread.currentThread().getName()+"正在运行第"+k+++"次");

try

{

sleep(SleepTime);

}

catch(InterruptedException e)

{

e.getStackTrace();

}

long end=System.currentTimeMillis();

time=time+end-start;

}

}

}

测试类Sleep_test类

package experiment.exp8;

import java.util.Scanner;

public class Sleep_test {

public static void main(String[] args) {

Scanner sc=new Scanner(System.in);

Sleep s1=new Sleep("线程一");

s1.SleepTime=1000;

s1.start();

s1.i=sc.nextInt();

System.out.println("线程一结束运行,启动线程二");

Sleep s2=new Sleep("线程二");

s2.SleepTime=5000;

s2.start();

s2.i=sc.nextInt();

System.out.println("线程二结束运行,启动线程三");

Sleep s3=new Sleep("线程三");

s3.SleepTime=10000;

s3.start();

s3.i=sc.nextInt();

System.out.println("线程三结束运行");

System.out.println("线程一运行时间:"+s1.time+""+"线程二运行时间:"+s2.time+""+"线程三运行时间:"+s3.time);

sc.close();

}

}

运行结果

8b7433fcd0e26825fbb621d602c5703d.png
<think>好的,我现在需要解决一个关于Android开发的问题:每隔80毫非常准时地执行一个方法。用户希望这个定时执行尽可能准确,所以我要仔细分析可能的方法和它们的优缺点。 首先,我想到Android中常用的定时任务方法,比如Handler.postDelayed、Timer、ScheduledExecutorService,还有AlarmManager。不过,这些方法各自有不同的特性和适用场景。比如,Handler和Timer可能在主线程运行,如果主线程有延迟,它们的执行时间可能不准确。而ScheduledExecutorService虽然比Timer更可靠,但仍然可能受系统负载影响。 然后,用户提到需要“非常准时”,所以可能需要更高精度的定时机制。Android系统本身并不是实时操作系统,所以绝对的准时可能很难,但可以尽量优化。接下来,我想到Choreographer,它通常用于VSync同步,比如在UI渲染时使用。它的FrameCallback可以提供一个相对精确的定时,因为它是基于屏幕刷新的频率(通常是60Hz,约16.6ms一帧)。不过,80ms大约是5帧的时间,这样可能通过累加帧数来实现每隔5执行一次。但这种方法是否可行呢?需要检查时间间隔是否准确,比如5*16.6≈83ms,接近但不完全准确,可能会有误差。不过如果用户可以接受轻微误差,这可能是一个选项。 另外,考虑使用Handler结合SystemClock.uptimeMillis()来补偿延迟。例如,每次执行任务后,计算下一次执行的时间点,如果发现延迟了,就调整后续的执行时间。这种方法需要自己实现一个循环,并在每次执行后重新调度任务,确保累积误差不会太大。这可能比简单的postDelayed更准确,因为每次都会修正下一次的时间点。 还有,Java中的ScheduledThreadPoolExecutor允许指定核心线程数,并且使用scheduleAtFixedRate方法。但这个方法的问题在于,如果任务执行时间超过间隔,或者系统繁忙,后续任务会被延迟或排队,导致时间不准确。不过,如果任务本身执行时间很短,可能影响较小。 另一个可能性是使用AlarmManager的setExact方法,但AlarmManager在较新的Android版本中精度可能受限,尤其是省电模式和其他优化可能会影响其准确性。此外,AlarmManager更适合较长时间间隔或唤醒设备执行任务,不太适合高频的80ms间隔。 然后,我还需要考虑是否需要在后台执行,如果应用在后台,某些定时方法可能被系统限制,导致任务无法准时执行。这种情况下,可能需要使用前台服务来保持进程优先级,但这会增加实现的复杂性。 此外,Android的WorkManager并不适合这种高频定时任务,它更多用于延迟任务和周期性任务,但最小间隔是15分钟,所以这里显然不适用。 再考虑Native层的方法,比如使用JNI调用C/C++代码,利用更高精度的定时器。但这样会增加开发难度,并且不同设备上的表现可能不一致,还可能引起兼容性问题。 综合以上分析,可能的解决方案是使用Choreographer的FrameCallback,结合Handler的自适应调度,或者使用一个独立的线程循环,通过精确的时间计算和睡眠来尽可能接近80ms的间隔。例如,在子线程中循环执行,计算每次执行的时间差,然后动态调整下一次的等待时间,使用SystemClock.sleep()或者更精确的等待方法,比如LockSupport.parkNanos(),来减少误差。 但是,需要注意的是,线程睡眠并不完全精确,尤其是在用户空间,可能会受到系统调度的影响。因此,即使这样,也无法保证绝对准时,但可以尽可能减少误差。 最后,可能需要测试不同方法在实际设备上的表现,选择最适合当前场景的方案。同时,需要考虑到任务执行的时间,如果任务本身耗时较长,必须确保其执行时间远小于80ms,否则无论哪种方法都会产生累积延迟。</think>在Android开发中实现每隔80ms准时执行方法,需综合考虑系统限制和精度需求。以下是分步解决方案及注意事项: --- ### **1. 常规方案及缺陷分析** - **`Handler.postDelayed()`/`Timer`** - **问题**:依赖主线程消息队列,易受UI操作或ANR影响,误差较大。 - **`ScheduledExecutorService`** - **改进**:使用独立线程(如`Executors.newSingleThreadScheduledExecutor()`),但仍受系统负载影响。 - **`AlarmManager`** - **不适用**:最小间隔为分钟级,且系统会限制精确唤醒。 --- ### **2. 高精度方案推荐** #### **方案一:Choreographer + 帧同步(适用于UI相关操作)** - **原理**:基于屏幕刷新率(通常60Hz≈16.67ms/帧),每5帧触发一次5×16.67≈83.3ms)。 - **实现**: ```kotlin val choreographer = Choreographer.getInstance() var frameCount = 0 val callback = object : Choreographer.FrameCallback { override fun doFrame(frameTimeNanos: Long) { frameCount++ if (frameCount % 5 == 0) { // 每5执行一次 yourMethod() frameCount = 0 } choreographer.postFrameCallback(this) } } choreographer.postFrameCallback(callback) ``` - **优点**:与VSync同步,稳定性高。 - **缺点**:间隔固定为83.3ms,存在约3ms误差。 --- #### **方案二:Handler + 动态补偿(最佳实践)** - **原理**:每次执行后计算下一次准确时间点,补偿延迟。 - **实现**: ```kotlin private val handler = Handler(Looper.getMainLooper()) private val interval = 80L private var nextTime = SystemClock.uptimeMillis() private val task = object : Runnable { override fun run() { val currentTime = SystemClock.uptimeMillis() yourMethod() // 计算下一次执行时间(动态补偿延迟) nextTime += interval val delay = nextTime - currentTime handler.postDelayed(this, maxOf(0, delay)) } } // 启动任务 handler.postDelayed(task, interval) ``` - **优点**:自动纠正累积误差,精度较高。 - **注意**:任务本身执行时间需远小于80ms。 --- #### **方案三:独立线程 + 精确休眠** - **原理**:在子线程中循环执行,通过`System.nanoTime()`高精度计时。 - **实现**: ```kotlin private val isRunning = AtomicBoolean(true) thread { var nextTime = System.nanoTime() val intervalNs = 80L * 1_000_000 // 80ms转纳 while (isRunning.get()) { yourMethod() // 计算下一次执行时间并休眠 nextTime += intervalNs val sleepTimeNs = nextTime - System.nanoTime() if (sleepTimeNs > 0) { LockSupport.parkNanos(sleepTimeNs) } else { // 超时,重置时间点避免累积延迟 nextTime = System.nanoTime() } } } ``` - **优点**:避开主线程干扰,精度更高。 - **缺点**:线程调度仍受系统影响,需处理生命周期(如页面退出时停止线程)。 --- ### **3. 注意事项** 1. **避免主线程阻塞**:任务逻辑需轻量,否则引发ANR。 2. **设备兼容性**:部分低端设备帧率可能波动(如60Hz→50Hz),影响方案一精度。 3. **后台限制**:应用退到后台时,系统可能限制CPU唤醒,需结合前台服务维持优先级。 4. **性能监控**:使用`Systrace`工具分析定时任务的实际执行间隔。 --- ### **4. 终极方案:Native层实现** 若对精度要求极高(如音视频同步),可通过JNI调用C/C++的`高精度定时器`(如`timerfd` + `epoll`): 1. 创建Native线程,使用`clock_nanosleep`或`pthread_cond_timedwait`。 2. 结合Linux的实时调度策略(`SCHED_FIFO`),需Root权限。 --- ### **总结** - **推荐方案**:优先使用 **Handler动态补偿**,平衡精度与实现复杂度。 - **极端需求**:考虑Native层方案,但需权衡维护成本和设备兼容性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值