rendered paste bodyExecutor:------------------------------------------------package net.sf.l2j.gameserver.model.job;import java.util.LinkedList;import java.util.concurrent.ScheduledThreadPoolExecutor;import java.util.concurrent.ThreadFactory;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;/** * @author zabbix * * Global tasks thread * */public class L2ExecutorService{ private static LinkedList<L2Job> _dequeue = new LinkedList<L2Job>(); private static ScheduledThreadPoolExecutor _executorService; private static L2ExecutorService _instance = null; public L2ExecutorService() { _executorService = new ScheduledThreadPoolExecutor(1, new ExecutorThreadFactory("ExecSvc", Thread.NORM_PRIORITY+1)); _executorService.scheduleAtFixedRate(new ExecuteJobs(),1000,100,TimeUnit.MILLISECONDS); } public static L2ExecutorService getInstance() { if(_instance == null) _instance = new L2ExecutorService(); return _instance; } private class ExecuteJobs implements Runnable { public void run() { synchronized(_dequeue) { int _jobsCount = _dequeue.size(); long serverFrame = System.currentTimeMillis(); for(int i=0;i<_jobsCount;i++) { L2Job job = _dequeue.poll(); if(job.getState() == L2JobState.JOBSTATE_TERMINATED) { _jobsCount--; continue; } if((serverFrame - job._frameOld) >= job._frameTime) job.Tick(); _dequeue.addLast(job); } } } } public L2Job addJob(L2Job job) { synchronized(_dequeue) { _dequeue.addLast(job); } return job; } public synchronized void flushJob(L2Job job) { int sp = _dequeue.indexOf(job); if(sp >= 0) _dequeue.get(sp).Terminate(); } public String getStats() { String ret = "====== L2ExecutorService stats ======\r\n"; synchronized(_dequeue) { ret += "Dequeue size: "+_dequeue.size()+"\r\n"; for (L2Job job : _dequeue) { ret += "Job: "+job._type+" period: "+job._frameTime+" state: "+job.getState()+"\r\n"; } } return ret; } private class ExecutorThreadFactory implements ThreadFactory { private int _prio; private String _name; private AtomicInteger _threadNumber = new AtomicInteger(1); public ExecutorThreadFactory(String name, int prio) { _prio = prio; _name = name; } /* (non-Javadoc) * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable) */ public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName(_name+"-"+_threadNumber.getAndIncrement()); t.setPriority(_prio); return t; } }}L2Job superclass #1:------------------------------------------------package net.sf.l2j.gameserver.model.job;public abstract class L2Job{ private int _owner; // owning L2Object protected L2JobType _type; private L2JobState _state; protected long _frameTime; protected long _frameOld; public L2Job() { _state = L2JobState.JOBSTATE_EXECUTION; _frameOld = System.currentTimeMillis(); } public void Terminate() { _state = L2JobState.JOBSTATE_TERMINATED; } public void Tick() { _frameOld = System.currentTimeMillis(); } public L2JobState getState() { return _state; } public void setOwner(int owner) { _owner = owner; } public int getOwner() { return _owner; }}L2Job superclass #2:------------------------------------------------package net.sf.l2j.gameserver.model.job;public enum L2JobState{ JOBSTATE_EXECUTION, JOBSTATE_TERMINATED}L2Job Superclass #3:------------------------------------------------package net.sf.l2j.gameserver.model.job;public enum L2JobType { JOB_FOLLOW, JOB_HIT_TASK, JOB_NOTIFY_AI, JOB_EVTTHINK_AI, JOB_ENABLE_SKILL, JOB_EFFECT}Job example #1:------------------------------------------------package net.sf.l2j.gameserver.model.job;import net.sf.l2j.gameserver.ai.CtrlEvent;import net.sf.l2j.gameserver.model.L2Character;import net.sf.l2j.gameserver.model.L2World;public class JobNotifyAI extends L2Job{ CtrlEvent _evt; public JobNotifyAI(int owner,CtrlEvent evt, long delay) { super(); setOwner(owner); _evt = evt; _frameTime = delay; _type = L2JobType.JOB_NOTIFY_AI; } public void Tick() { super.Tick(); L2Character owner = L2World.getInstance().safeCastCreature("notiyAITick",getOwner()); if(owner != null && owner.getAI() != null) owner.getAI().notifyEvent(_evt,null); Terminate(); }}Job example #2:------------------------------------------------package net.sf.l2j.gameserver.model.job;import net.sf.l2j.gameserver.model.L2Character;import net.sf.l2j.gameserver.model.L2World;public class JobHitTask extends L2Job{ int _target; int _dmg; boolean _crit; boolean _miss; boolean _ss; boolean _shield; public JobHitTask(int owner,int target, int damage, boolean crit, boolean miss, boolean soulshot, boolean shld, long delay) { super(); setOwner(owner); _target = target; _dmg = damage; _crit = crit; _miss = miss; _ss = soulshot; _shield = shld; _frameTime = delay; _type = L2JobType.JOB_HIT_TASK; } public void Tick() { super.Tick(); L2Character actor = L2World.getInstance().safeCastCreature("hitTickActor",getOwner()); L2Character target = L2World.getInstance().safeCastCreature("hitTickTarget",_target); //FIXME: // target может быть null // это отрабатывается в onHitTimer (AINotifyEvent.CANCEL) if(actor != null) actor.onHitTimer(target,_dmg,_crit,_miss,_ss,_shield); Terminate(); }}