如何處理自定義線程模型---java_第1頁
如何處理自定義線程模型---java_第2頁
如何處理自定義線程模型---java_第3頁
如何處理自定義線程模型---java_第4頁
如何處理自定義線程模型---java_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、如何處理自定義線程模型-java看過我之前文章的園友可能知道我是做游戲開發(fā),我的很多思路和出發(fā)點是按照游戲思路來處理的,所以和web的話可能會有沖突,不相符合。來說說為啥我要自定義線程模型呢?按照我做的mmorpg或者mmoarpg游戲劃分,線程被劃分為,主線程,全局同步線程,聊天線程,組隊線程,地圖線程,以及地圖消息分發(fā)派送線程等;一些列,都需要根據(jù)我的劃分,以及數(shù)據(jù)流向做控制。游戲服務器,主要要做的事情,肯定是接受玩家的 命令請求 -> 相應的操作 -> 返回結(jié)果;在服務器端所有的消息都會注冊到消息管理器里,然后消息在注冊的時候會指定線程模型,如果消息需要提交到玩家所在地圖線程

2、進行處理的話注冊消息的時候就要把線程模型用(地圖消息分發(fā)派送線程);下面我們先來分析線程模型;在看線程模型代碼之前我先看看我的任務模型 復制代碼 1 package net.sz.engine.thread; 2 3 import java.io.Serializable; 4 import org.apache.log4j.Logger; 5 import net.sz.engine.structs.ObjectAttribute; 6 import net.sz.engine.structs.ObjectGlobal; 7 8 /* 9 * 任務模型10 *11 * <br>1

3、2 * author 失足程序員<br>13 * mail 492794628<br>14 * phonelt;br>15 */16 public abstract class TaskEvent implements Serializable, Cloneable 17 18 private static final Logger log = Logger.getLogger(TaskEvent.class);19 private static final long serialVersionUID = 4196020659994845

4、804L;20 21 /運行時數(shù)據(jù)22 private transient final ObjectAttribute runOther = new ObjectAttribute();23 /任務創(chuàng)建的時間24 protected long createTime;25 /任務的唯一id26 protected long taskId;27 /取消的任務28 protected boolean cancel = false;29 30 public TaskEvent() 31 this.runOther.put("submitTime", System.currentTi

5、meMillis();32 createTime = System.currentTimeMillis();33 cancel = false;34 taskId = ObjectGlobal.getUUID();35 36 37 public long getCreateTime() 38 return createTime;39 40 41 public void setCreateTime(long createTime) 42 this.createTime = createTime;43 44 45 public long getSubmitTime() 46 return this

6、.runOther.getlongValue("submitTime");47 48 49 public ObjectAttribute getRunOther() 50 return runOther;51 52 53 public boolean isCancel() 54 return cancel;55 56 57 public void setCancel(boolean cancel) 58 this.cancel = cancel;59 60 61 public abstract void run();62 63 Override64 public Objec

7、t clone() throws CloneNotSupportedException 65 return super.clone(); /To change body of generated methods, choose Tools | Templates.66 67 68 復制代碼復制代碼 1 package net.sz.engine.thread; 2 3 /* 4 * 定時器執(zhí)行器 5 * 6 * <br> 7 * author 失足程序員<br> 8 * mail 492794628<br> 9 * phonelt;

8、br> 10 */ 11 public abstract class TimerTaskEvent extends TaskEvent 12 13 private static final long serialVersionUID = -8331296295264699207L; 14 15 /* 16 * 開始執(zhí)行的時間 17 */ 18 protected long startTime; 19 20 /* 21 * 是否一開始執(zhí)行一次 22 */ 23 protected boolean startAction; 24 25 /* 26 * 結(jié)束時間 27 */ 28 protec

9、ted long endTime; 29 30 /* 31 * 執(zhí)行次數(shù) 32 */ 33 protected int actionCount; 34 35 /* 36 * 間隔執(zhí)行時間 37 */ 38 protected int intervalTime; 39 40 /* 41 * 42 * param startTime 指定開始時間 43 * param isStartAction 是否一開始就執(zhí)行一次 44 * param endTime 指定結(jié)束時間 45 * param actionCount 指定執(zhí)行次數(shù) 46 * param intervalTime 指定間隔時間 47 *

10、/ 48 public TimerTaskEvent(long startTime, boolean isStartAction, long endTime, int actionCount, int intervalTime) 49 super(); 50 this.startTime = startTime; 51 this.startAction = isStartAction; 52 this.endTime = endTime; 53 this.actionCount = actionCount; 54 ervalTime = intervalTime; 55 56

11、57 /* 58 * 指定任務的開始執(zhí)行時間 59 * 60 * param startTime 指定開始時間 61 * param isStartAction 是否一開始就執(zhí)行一次 62 * param actionCount 指定執(zhí)行次數(shù) 63 * param intervalTime 指定間隔時間 64 */ 65 public TimerTaskEvent(long startTime, boolean isStartAction, int actionCount, int intervalTime) 66 this(startTime, isStartAction, 0, actio

12、nCount, intervalTime); 67 68 69 /* 70 * 指定結(jié)束時間已結(jié)束時間為準,執(zhí)行次數(shù)不一定夠 71 * 72 * param isStartAction 是否一開始就執(zhí)行一次 73 * param endTime 指定結(jié)束時間 74 * param actionCount 指定執(zhí)行次數(shù) 75 * param intervalTime 指定間隔時間 76 * 77 */ 78 public TimerTaskEvent(boolean isStartAction, long endTime, int actionCount, int intervalTime) 7

13、9 this(0, isStartAction, endTime, actionCount, intervalTime); 80 81 82 /* 83 * 指定開始時間,和結(jié)束時間 84 * 85 * param startTime 指定開始時間 86 * param endTime 指定結(jié)束時間 87 * param intervalTime 指定間隔時間 88 */ 89 public TimerTaskEvent(long startTime, long endTime, int intervalTime) 90 this(startTime, false, endTime, -1,

14、intervalTime); 91 92 93 /* 94 * 指定的執(zhí)行次數(shù)和間隔時間 95 * 96 * param actionCount 指定執(zhí)行次數(shù) 97 * param intervalTime 指定間隔時間 98 */ 99 public TimerTaskEvent(int actionCount, int intervalTime) 100 this(0, false, 0, actionCount, intervalTime);101 102 103 /*104 * 提交后指定的時間無限制執(zhí)行105 *106 * param intervalTime 指定間隔時間107 *

15、/108 public TimerTaskEvent(int intervalTime) 109 this(0, false, 0, -1, intervalTime);110 111 112 public long getStartTime() 113 return startTime;114 115 116 public void setStartTime(long startTime) 117 this.startTime = startTime;118 119 120 public boolean isStartAction() 121 return startAction;122 1

16、23 124 public void setStartAction(boolean startAction) 125 this.startAction = startAction;126 127 128 public long getEndTime() 129 return endTime;130 131 132 public void setEndTime(long endTime) 133 this.endTime = endTime;134 135 136 public int getActionCount() 137 return actionCount;138 139 140 pub

17、lic void setActionCount(int actionCount) 141 this.actionCount = actionCount;142 143 144 public int getIntervalTime() 145 return intervalTime;146 147 148 public void setIntervalTime(int intervalTime) 149 ervalTime = intervalTime;150 151 152 復制代碼這里是任務模型和定時器任務模型;復制代碼 1 package net.sz.engine.thr

18、ead; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.concurrent.ConcurrentLinkedQueue; 6 import net.sz.engine.structs.ObjectGlobal; 7 import net.sz.engine.utils.MailUtil; 8 import net.sz.engine.utils.StringUtil; 9 import org.apache.log4j.Logger; 10 import org.jboss.jandex

19、.Main; 11 12 /* 13 * 線程模型 14 * <br> 15 * author 失足程序員<br> 16 * mail 492794628<br> 17 * phonelt;br> 18 */ 19 public class ThreadModel implements Runnable 20 21 private static final Logger log = Logger.getLogger(ThreadModel.class); 22 private static long threadID = 0;

20、 23 protected static final Object SYN_OBJECT = new Object(); 24 protected long tid; 25 protected String name; 26 protected long lastSendMail = 0; 27 28 protected final ArrayList<MyThread> threads = new ArrayList<>(); 29 /* 30 * 任務列表 線程安全的任務列表 31 */ 32 /protected final List<TaskModel&g

21、t; taskQueue = new ArrayList<>(); 33 protected final ConcurrentLinkedQueue<TaskEvent> taskQueue = new ConcurrentLinkedQueue<>(); 34 35 /* 36 * 37 */ 38 protected final List<TimerTaskEvent> timerQueue = new ArrayList<>(); 39 40 / false標識刪除線程 41 protected volatile boolean

22、 runing = true; 42 43 public ThreadModel(ThreadGroup group) 44 this(group, "無名", 1); 45 46 47 public ThreadModel(String name) 48 this(ThreadPool.UnknownThreadGroup, name, 1); 49 50 51 public ThreadModel(ThreadGroup group, String name, int threadCount) 52 this(group, name, threadCount, null

23、); 53 54 55 public ThreadModel(ThreadGroup group, String name, int threadCount, Runnable runnable) 56 synchronized (SYN_OBJECT) 57 threadID+; 58 tid = threadID; 59 60 for (int i = 1; i <= threadCount; i+) 61 MyThread thread; 62 if (runnable = null) 63 thread = new MyThread(tid, group, this, name

24、+ "-" + tid + "-" + i); 64 else 65 thread = new MyThread(tid, group, runnable, name + "-" + tid + "-" + i); 66 67 thread.start(); 68 threads.add(thread); 69 70 = name; 71 72 73 /* 74 * 線程名字 75 * 76 * return 77 */ 78 public String getName() 79 return

25、name; 80 81 82 /* 83 * 獲取線程的自定義id 84 * 85 * return 86 */ 87 public long getId() 88 return this.tid; 89 90 91 /* 92 * 增加新的任務 每增加一個新任務,都要喚醒任務隊列 93 * 94 * param runnable 95 */ 96 public void addTask(TaskEvent runnable) 97 taskQueue.add(runnable); 98 99 synchronized (taskQueue) 100 /* 喚醒隊列, 開始執(zhí)行 */101 t

26、askQueue.notifyAll();102 103 104 105 /*106 * 向線程添加定時器任務107 *108 * param runnable109 */110 public void addTimer(TimerTaskEvent runnable) 111 synchronized (timerQueue) 112 if (runing) 113 /一開始執(zhí)行一次114 if (runnable.startAction) 115 addTask(runnable);116 117 timerQueue.add(runnable);118 else 119 log.erro

27、r("線程已經(jīng)停止");120 121 122 123 124 / <editor-fold defaultstate="collapsed" desc="定時器線程執(zhí)行器 public void timerRun()">125 /*126 * 定時器線程執(zhí)行器127 */128 public void timerRun() 129 ArrayList<TimerTaskEvent> taskModels;130 synchronized (timerQueue) 131 / 隊列不為空的情況下 取出隊列定時器

28、任務132 taskModels = new ArrayList<>(timerQueue);133 134 if (!taskModels.isEmpty() 135 for (TimerTaskEvent timerEvent : taskModels) 136 int execCount = timerEvent.getRunOther().getintValue("Execcount");137 long lastTime = timerEvent.getRunOther().getlongValue("LastExecTime");

29、138 long nowTime = System.currentTimeMillis();139 if (lastTime = 0) 140 timerEvent.getRunOther().put("LastExecTime", nowTime);141 else if (timerEvent.isCancel() 142 /如果任務已經(jīng)取消143 synchronized (timerQueue) 144 timerQueue.remove(timerEvent);145 146 log.debug("清理定時器任務:" + timerEvent.

30、getClass().getName();147 else if (nowTime > timerEvent.getStartTime() / 是否滿足開始時間148 && (nowTime - timerEvent.getSubmitTime() > timerEvent149 .getIntervalTime()/ 提交以后是否滿足了間隔時間150 && (timerEvent.getEndTime() <= 0 | nowTime < timerEvent151 .getEndTime() / 判斷結(jié)束時間152 &&

31、; (nowTime - lastTime >= timerEvent153 .getIntervalTime() / 判斷上次執(zhí)行到目前是否滿足間隔時間154 155 / 提交執(zhí)行定時器最先執(zhí)行156 this.addTask(timerEvent);157 / 記錄158 execCount+;159 timerEvent.getRunOther().put("Execcount", execCount);160 timerEvent.getRunOther().put("LastExecTime", nowTime);161 nowTime

32、= System.currentTimeMillis();162 / 判斷刪除條件163 if (timerEvent.getEndTime() > 0 && nowTime < timerEvent.getEndTime()164 | (timerEvent.getActionCount() > 0 && timerEvent.getActionCount() <= execCount) 165 synchronized (timerQueue) 166 timerQueue.remove(timerEvent);167 168 log

33、.debug("清理定時器任務:" + timerEvent.getClass().getName();169 170 171 172 173 174 / </editor-fold>175 176 / <editor-fold defaultstate="collapsed" desc="查看線程堆棧 public void showStackTrace()">177 /*178 *179 * 查看線程堆棧180 */181 public void showStackTrace() 182 StringBui

34、lder buf = new StringBuilder();183 for (MyThread currentThread : threads) 184 long procc = System.currentTimeMillis() - currentThread.getLastExecuteTime();185 if (procc > 5 * 1000 && procc < 864000000L) /小于10天/因為多線程操作時間可能不準確186 buf.append("線程")187 .append(currentThread.getNam

35、e()188 .append("可能已卡死 -> ")189 .append(procc / 1000f)190 .append("sn ")191 .append("執(zhí)行任務:")192 .append(currentThread.getLastCommand().getClass().getName();193 try 194 StackTraceElement elements = currentThread.getStackTrace();195 for (int i = 0; i < elements.lengt

36、h; i+) 196 buf.append("n ")197 .append(elementsi.getClassName()198 .append(".")199 .append(elementsi.getMethodName()200 .append("(").append(elementsi.getFileName()201 .append("")202 .append(elementsi.getLineNumber().append(")");203 204 catch (Excepti

37、on e) 205 buf.append(e);206 207 buf.append("n+");208 209 210 String toString = buf.toString();211 if (!StringUtil.isNullOrEmpty(toString) 212 log.error(toString);213 if (System.currentTimeMillis() - lastSendMail > 5 * 60 * 1000) 214 lastSendMail = System.currentTimeMillis();215 MailUtil

38、.sendMail("線程執(zhí)行已卡死 -> 游戲id-" + ObjectGlobal.GameID + " 平臺-" + ObjectGlobal.Platform + " 服務器id-" + ObjectGlobal.ServerID, toString);216 217 218 219 / </editor-fold>220 221 Override222 public void run() 223 MyThread currentThread = (MyThread) Thread.currentThread

39、();224 while (runing) 225 while (taskQueue.isEmpty() && runing) 226 try 227 /* 任務隊列為空,則等待有新任務加入從而被喚醒 */228 synchronized (taskQueue) 229 taskQueue.wait(500);230 231 catch (InterruptedException ie) 232 log.error(ie);233 234 235 /* 取出任務執(zhí)行 */236 if (runing) 237 currentThread.lastCommand = null;2

40、38 currentThread.lastCommand = taskQueue.poll();239 240 if (currentThread.lastCommand != null) 241 if (currentThread.lastCommand.isCancel() 242 /如果任務已經(jīng)取消243 continue;244 245 /* 執(zhí)行任務 */246 / r.setSubmitTimeL();247 currentThread.lastExecuteTime = System.currentTimeMillis();248 try 249 currentThread.la

41、stCommand.run();250 catch (Exception e) 251 log.error("工人<“" + currentThread.getName() + "”> 執(zhí)行任務<" + currentThread.lastCommand.getClass().getName() + "> 遇到錯誤: ", e);252 253 long timeL1 = System.currentTimeMillis() - currentThread.lastExecuteTime;254 if (tim

42、eL1 <= 20) 255 256 else if (timeL1 <= 100L) 257 ("工人<“" + currentThread.getName() + "”> 完成了任務:" + currentThread.lastCommand.toString() + " 執(zhí)行耗時:" + timeL1);258 else if (timeL1 <= 200L) 259 ("工人<“" + currentThread.getName() + &

43、quot;”> 長時間執(zhí)行 完成任務:" + currentThread.lastCommand.toString() + " “考慮”任務腳本邏輯 耗時:" + timeL1);260 else 261 ("工人<“" + currentThread.getName() + "”> 超長時間執(zhí)行完成 任務:" + currentTCommand.toString() + " “考慮是否應該刪除”任務腳本 耗時:" + timeL1);262 263 currentThr

44、ead.lastExecuteTime = 0;264 265 266 log.error("線程結(jié)束, 工人<“" + Thread.currentThread().getName() + "”>退出");267 268 269 /*270 * 自定義線程271 */272 public class MyThread extends Thread 273 274 /*275 *276 * param tid 自定義線程id277 * param group 分組278 * param run 執(zhí)行方法279 * param name 線程名稱280 */281 public MyThread(long tid, ThreadGroup group, Runnable run, String name) 282 super(group, run, name);283 this._id = tid;284 285 286 /線程的自定義id287 public long _id;288 /正在執(zhí)行的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論