IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Java Timer定时器 -> 正文阅读

[游戏开发]Java Timer定时器

在Java 1.3中 发布了早期的定时器Timer(已经过时,存在设计问题)

TimerTask

public abstract class TimerTask implements Runnable {
    /**
     * This object is used to control access to the TimerTask internals.
     */
    final Object lock = new Object();
    int state = VIRGIN;
    static final int VIRGIN = 0;
    static final int SCHEDULED   = 1;
    static final int EXECUTED    = 2;
    static final int CANCELLED   = 3;
}

TaskQueue

class TaskQueue {
    private TimerTask[] queue = new TimerTask[128];
}

TimerThread

class TimerThread extends Thread {
    boolean newTasksMayBeScheduled = true;
    private TaskQueue queue;
    TimerThread(TaskQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            mainLoop();
        } finally {
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }

    /**
     * The main timer loop.  (See class comment.)
     */
    private void mainLoop() {
        while (true) {
            try {
                TimerTask task;
                boolean taskFired;
                synchronized(queue) {
                    // Wait for queue to become non-empty
                    while (queue.isEmpty() && newTasksMayBeScheduled)
                        queue.wait();
                    if (queue.isEmpty())
                        break; // Queue is empty and will forever remain; die

                    // Queue nonempty; look at first evt and do the right thing
                    long currentTime, executionTime;
                    task = queue.getMin();
                    synchronized(task.lock) {
                        if (task.state == TimerTask.CANCELLED) {
                            queue.removeMin();
                            continue;  // No action required, poll queue again
                        }
                        currentTime = System.currentTimeMillis();
                        executionTime = task.nextExecutionTime;
                        if (taskFired = (executionTime<=currentTime)) {
                            if (task.period == 0) { // Non-repeating, remove
                                queue.removeMin();
                                task.state = TimerTask.EXECUTED;
                            } else { // Repeating task, reschedule
                                queue.rescheduleMin(
                                  task.period<0 ? currentTime   - task.period
                                                : executionTime + task.period);
                            }
                        }
                    }
                    if (!taskFired) // Task hasn't yet fired; wait
                        queue.wait(executionTime - currentTime);
                }
                if (taskFired)  // Task fired; run it, holding no locks
                    task.run();
            } catch(InterruptedException e) {
            }
        }
    }
}

Timer

public class Timer {
	//定时器任务队列
    private final TaskQueue queue = new TaskQueue();
	//定时器线程
    private final TimerThread thread = new TimerThread(queue);
}

由此可见Timer使用单线程(TimerThread)轮询任务队列(TimerQueue)的方式执行任务,并且由于在java1.3版本的时候,还没有Lock的实现,线程同步是通过Synchronized关键字实现,因此一旦某个任务失败,那么后续的任务都将受到影响。并且此时的TimerTask都是实现Runnable接口,因此任务执行后也不能返回对应的返回结果

总结:

  1. Timer 单线程调度
  2. 所有任务的执行不能返回执行结果
  3. 一旦某一任务执行失败,后续的任务都会受到影响
  4. 简单易用

在Java 1.5中 发布了ScheduledExecutorService来取代Timer,优化了诸多缺点

ScheduledExecutorService

/*
 * @since 1.5
 */
public interface ScheduledExecutorService extends ExecutorService {
    public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
    public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);  
    //调度方式1:在上一任务执行开始时延迟(initialDelay)时间再继续执行任务
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); 
    //调度方式2: 在上一任务执行结束后延迟(initialDelay)时间再继续执行任务                                  
	public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);                                                                                                                                 
}

ThreadPoolExecutor

public class ThreadPoolExecutor extends AbstractExecutorService {
//使用阻塞队列
    private final BlockingQueue<Runnable> workQueue;
   	//使用重入锁
    private final ReentrantLock mainLock = new ReentrantLock();
    private final Condition termination = mainLock.newCondition();
    /**
     * Set containing all worker threads in pool. Accessed only when
     * holding mainLock.
     */
    private final HashSet<Worker> workers = new HashSet<Worker>();
    //使用线程工厂创建线程
    private volatile ThreadFactory threadFactory;
    /**
     * Handler called when saturated or shutdown in execute.
     */    
    private volatile RejectedExecutionHandler handler;

	//初始化线程池
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,  long keepAliveTime, TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }
	
	//工作线程
	private final class Worker extends AbstractQueuedSynchronizer implements Runnable
    {
		final Thread thread;
		Runnable firstTask;
		Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }
    }
}

ScheduledThreadPoolExecutor

public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService {
		private class ScheduledFutureTask<V> extends FutureTask<V> implements RunnableScheduledFuture<V> {
			 /** The time the task is enabled to execute in nanoTime units */
			 private long time;
	        /**
	         * Period in nanoseconds for repeating tasks.  A positive
	         * value indicates fixed-rate execution.  A negative value
	         * indicates fixed-delay execution.  A value of 0 indicates a
	         * non-repeating task.
	         */
	        private final long period;
			/** The actual task to be re-enqueued by reExecutePeriodic */
        	RunnableScheduledFuture<V> outerTask = this;
		}

		// 延迟的任务队列,初始化容量为16
		static class DelayedWorkQueue extends AbstractQueue<Runnable>  implements BlockingQueue<Runnable> {
			private static final int INITIAL_CAPACITY = 16;
        	private RunnableScheduledFuture<?>[] queue =  new RunnableScheduledFuture<?>[INITIAL_CAPACITY];
        	private final ReentrantLock lock = new ReentrantLock();
			.......
		}		
	}
}

对于过时且存在设计缺陷的Timer, ScheduledThreadPoolExecutor通过设置线程池来实现多线程的执行,同时将任务放入阻塞队列中,使用ReentrantLock实现线程之间的同步(并且在任务执行异常后并不会对后续任务的执行造成影响),同时自Java1.5后,任务允许加入无返回结果的Runnable实现也允许加入存在返回结果的Callable的实现。

总结:

  1. ScheduledThreadPoolExecutor多线程调度
  2. 即允许执行存在返回值的任务(Callable) ,也允许执行无返回结果的任务(Runnable)
  3. 使用重入锁,任务执行异常不会对其他任务执行造成影响
  4. 使用线程池的概念,线程的利用率高
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-15 12:05:56  更:2021-10-15 12:06:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:33:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码