看我是如何处理自定义线程模型---java

看过我之前文章的园友可能知道我是做游戏开发,我的很多思路和出发点是按照游戏思路来处理的,所以和web的话可能会有冲突,不相符合。

来说说为啥我要自定义线程模型呢?

按照我做的mmorpg或者mmoarpg游戏划分,线程被划分为,主线程,全局同步线程,聊天线程,组队线程,地图线程,以及地图消息分发派送线程等;

一些列,都需要根据我的划分,以及数据流向做控制。

游戏服务器,主要要做的事情,肯定是接受玩家的 命令请求 -> 相应的操作 -> 返回结果;
在服务器端所有的消息都会注册到消息管理器里,然后消息在注册的时候会指定线程模型,
如果消息需要提交到玩家所在地图线程进行处理的话注册消息的时候就要把线程模型用(地图消息分发派送线程);

下面我们先来分析线程模型;

在看线程模型代码之前我先看看我的任务模型

 

 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>
12  * author 失足程序员<br>
13  * mail 492794628@qq.com<br>
14  * phone 13882122019<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 = 4196020659994845804L;
20 
21     //运行时数据
22     private transient final ObjectAttribute runOther = new ObjectAttribute();
23     //任务创建的时间
24     protected long createTime;
25     //任务的唯一id
26     protected long taskId;
27     //取消的任务
28     protected boolean cancel = false;
29 
30     public TaskEvent() {
31         this.runOther.put("submitTime", System.currentTimeMillis());
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.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     @Override
64     public Object 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  * 定时器执行器
  5  *
  6  * <br>
  7  * author 失足程序员<br>
  8  * mail 492794628@qq.com<br>
  9  * phone 13882122019<br>
 10  */
 11 public abstract class TimerTaskEvent extends TaskEvent {
 12 
 13     private static final long serialVersionUID = -8331296295264699207L;
 14 
 15     /**
 16      * 开始执行的时间
 17      */
 18     protected long startTime;
 19 
 20     /**
 21      * 是否一开始执行一次
 22      */
 23     protected boolean startAction;
 24 
 25     /**
 26      * 结束时间
 27      */
 28     protected long endTime;
 29 
 30     /**
 31      * 执行次数
 32      */
 33     protected int actionCount;
 34 
 35     /**
 36      * 间隔执行时间
 37      */
 38     protected int intervalTime;
 39 
 40     /**
 41      *
 42      * @param startTime 指定开始时间
 43      * @param isStartAction 是否一开始就执行一次
 44      * @param endTime 指定结束时间
 45      * @param actionCount 指定执行次数
 46      * @param intervalTime 指定间隔时间
 47      */
 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         this.intervalTime = intervalTime;
 55     }
 56 
 57     /**
 58      * 指定任务的开始执行时间
 59      *
 60      * @param startTime 指定开始时间
 61      * @param isStartAction 是否一开始就执行一次
 62      * @param actionCount 指定执行次数
 63      * @param intervalTime 指定间隔时间
 64      */
 65     public TimerTaskEvent(long startTime, boolean isStartAction, int actionCount, int intervalTime) {
 66         this(startTime, isStartAction, 0, actionCount, intervalTime);
 67     }
 68 
 69     /**
 70      * 指定结束时间已结束时间为准,执行次数不一定够
 71      *
 72      * @param isStartAction 是否一开始就执行一次
 73      * @param endTime 指定结束时间
 74      * @param actionCount 指定执行次数
 75      * @param intervalTime 指定间隔时间
 76      *
 77      */
 78     public TimerTaskEvent(boolean isStartAction, long endTime, int actionCount, int intervalTime) {
 79         this(0, isStartAction, endTime, actionCount, intervalTime);
 80     }
 81 
 82     /**
 83      * 指定开始时间,和结束时间
 84      *
 85      * @param startTime 指定开始时间
 86      * @param endTime 指定结束时间
 87      * @param intervalTime 指定间隔时间
 88      */
 89     public TimerTaskEvent(long startTime, long endTime, int intervalTime) {
 90         this(startTime, false, endTime, -1, intervalTime);
 91     }
 92 
 93     /**
 94      * 指定的执行次数和间隔时间
 95      *
 96      * @param actionCount 指定执行次数
 97      * @param intervalTime 指定间隔时间
 98      */
 99     public TimerTaskEvent(int actionCount, int intervalTime) {
100         this(0, false, 0, actionCount, intervalTime);
101     }
102 
103     /**
104      * 提交后指定的时间无限制执行
105      *
106      * @param intervalTime 指定间隔时间
107      */
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     }
123 
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     public 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         this.intervalTime = intervalTime;
150     }
151 
152 }

这里是任务模型和定时器任务模型;

  1 package net.sz.engine.thread;
  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.Main;
 11 
 12 /**
 13  * 线程模型
 14  * <br>
 15  * author 失足程序员<br>
 16  * mail 492794628@qq.com<br>
 17  * phone 13882122019<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;
 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> 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 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);
 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 + "-" + tid + "-" + i);
 64             } else {
 65                 thread = new MyThread(tid, group, runnable, name + "-" + tid + "-" + i);
 66             }
 67             thread.start();
 68             threads.add(thread);
 69         }
 70         this.name = name;
 71     }
 72 
 73     /**
 74      * 线程名字
 75      *
 76      * @return
 77      */
 78     public String getName() {
 79         return 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             /* 唤醒队列, 开始执行 */
101             taskQueue.notifyAll();
102         }
103     }
104 
105     /**
106      * 向线程添加定时器任务
107      *
108      * @param runnable
109      */
110     public void addTimer(TimerTaskEvent runnable) {
111         synchronized (timerQueue) {
112             if (runing) {
113                 //一开始执行一次
114                 if (runnable.startAction) {
115                     addTask(runnable);
116                 }
117                 timerQueue.add(runnable);
118             } else {
119                 log.error("线程已经停止");
120             }
121         }
122     }
123 
124     // <editor-fold defaultstate="collapsed" desc="定时器线程执行器 public void timerRun()">
125     /**
126      * 定时器线程执行器
127      */
128     public void timerRun() {
129         ArrayList<TimerTaskEvent> taskModels;
130         synchronized (timerQueue) {
131             // 队列不为空的情况下 取出队列定时器任务
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");
138                 long nowTime = System.currentTimeMillis();
139                 if (lastTime == 0) {
140                     timerEvent.getRunOther().put("LastExecTime", nowTime);
141                 } else if (timerEvent.isCancel()) {
142                     //如果任务已经取消
143                     synchronized (timerQueue) {
144                         timerQueue.remove(timerEvent);
145                     }
146                     log.debug("清理定时器任务:" + timerEvent.getClass().getName());
147                 } else if (nowTime > timerEvent.getStartTime() // 是否满足开始时间
148                         && (nowTime - timerEvent.getSubmitTime() > timerEvent
149                         .getIntervalTime())// 提交以后是否满足了间隔时间
150                         && (timerEvent.getEndTime() <= 0 || nowTime < timerEvent
151                         .getEndTime()) // 判断结束时间
152                         && (nowTime - lastTime >= timerEvent
153                         .getIntervalTime())) // 判断上次执行到目前是否满足间隔时间
154                 {
155                     // 提交执行定时器最先执行
156                     this.addTask(timerEvent);
157                     // 记录
158                     execCount++;
159                     timerEvent.getRunOther().put("Execcount", execCount);
160                     timerEvent.getRunOther().put("LastExecTime", nowTime);
161                     nowTime = 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.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         StringBuilder 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.getName())
188                         .append("]可能已卡死 -> ")
189                         .append(procc / 1000f)
190                         .append("s\n    ")
191                         .append("执行任务:")
192                         .append(currentThread.getLastCommand().getClass().getName());
193                 try {
194                     StackTraceElement[] elements = currentThread.getStackTrace();
195                     for (int i = 0; i < elements.length; i++) {
196                         buf.append("\n    ")
197                                 .append(elements[i].getClassName())
198                                 .append(".")
199                                 .append(elements[i].getMethodName())
200                                 .append("(").append(elements[i].getFileName())
201                                 .append(";")
202                                 .append(elements[i].getLineNumber()).append(")");
203                     }
204                 } catch (Exception 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.sendMail("线程执行已卡死 -> 游戏id-" + ObjectGlobal.GameID + "  平台-" + ObjectGlobal.Platform + "  服务器id-" + ObjectGlobal.ServerID, toString);
216             }
217         }
218     }
219     // </editor-fold>
220 
221     @Override
222     public void run() {
223         MyThread currentThread = (MyThread) Thread.currentThread();
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             /* 取出任务执行 */
236             if (runing) {
237                 currentThread.lastCommand = null;
238                 currentThread.lastCommand = taskQueue.poll();
239             }
240             if (currentThread.lastCommand != null) {
241                 if (currentThread.lastCommand.isCancel()) {
242                     //如果任务已经取消
243                     continue;
244                 }
245                 /* 执行任务 */
246                 // r.setSubmitTimeL();
247                 currentThread.lastExecuteTime = System.currentTimeMillis();
248                 try {
249                     currentThread.lastCommand.run();
250                 } catch (Exception e) {
251                     log.error("工人<“" + currentThread.getName() + "”> 执行任务<" + currentThread.lastCommand.getClass().getName() + "> 遇到错误: ", e);
252                 }
253                 long timeL1 = System.currentTimeMillis() - currentThread.lastExecuteTime;
254                 if (timeL1 <= 20) {
255 
256                 } else if (timeL1 <= 100L) {
257                     log.info("工人<“" + currentThread.getName() + "”> 完成了任务:" + currentThread.lastCommand.toString() + " 执行耗时:" + timeL1);
258                 } else if (timeL1 <= 200L) {
259                     log.info("工人<“" + currentThread.getName() + "”> 长时间执行 完成任务:" + currentThread.lastCommand.toString() + " “考虑”任务脚本逻辑 耗时:" + timeL1);
260                 } else {
261                     log.info("工人<“" + currentThread.getName() + "”> 超长时间执行完成 任务:" + currentThread.lastCommand.toString() + " “考虑是否应该删除”任务脚本 耗时:" + timeL1);
262                 }
263                 currentThread.lastExecuteTime = 0;
264             }
265         }
266         log.error("线程结束, 工人<“" + Thread.currentThread().getName() + "”>退出");
267     }
268 
269     /**
270      * 自定义线程
271      */
272     public class MyThread extends Thread {
273 
274         /**
275          *
276          * @param tid 自定义线程id
277          * @param group 分组
278          * @param run 执行方法
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         //线程的自定义id
287         public long _id;
288         //正在执行的任务
289         public volatile TaskEvent lastCommand;
290         //开始执行任务的时间
291         public volatile long lastExecuteTime = 0;
292 
293         public TaskEvent getLastCommand() {
294             return lastCommand;
295         }
296 
297         public long getLastExecuteTime() {
298             return lastExecuteTime;
299         }
300 
301         /**
302          * 返回线程自定义id
303          *
304          * @return
305          */
306         @Override
307         public long getId() {
308             return _id;
309         }
310 
311     }
312 
313     /**
314      * 停止线程,设置线程的停止状态,并不会马上终止线程
315      */
316     public void stop() {
317         this.runing = false;
318     }
319 
320     public boolean isRuning() {
321         return runing;
322     }
323 
324     @Override
325     public String toString() {
326         return "Thread{" + "tid=" + tid + ",Name=" + this.getName() + '}';
327     }
328 
329 }

我从 ThreadModel 构造函数的

 1     public ThreadModel(ThreadGroup group, String name, int threadCount, Runnable runnable) {
 2         synchronized (SYN_OBJECT) {
 3             threadID++;
 4             tid = threadID;
 5         }
 6         for (int i = 1; i <= threadCount; i++) {
 7             MyThread thread;
 8             if (runnable == null) {
 9                 thread = new MyThread(tid, group, this, name + "-" + tid + "-" + i);
10             } else {
11                 thread = new MyThread(tid, group, runnable, name + "-" + tid + "-" + i);
12             }
13             thread.start();
14             threads.add(thread);
15         }
16         this.name = name;
17     }

可以看出,这里我运行声明一个或者多个 MyThread  线程类

为什么要这样考虑呢打个比方,如果是处理日志的写入数据这种,没有共享数据,没有线程临界区的处理流程,我可以考虑使用N个线程去处理这样的工作;不会产生脏数据;

如果是想组队请求,技能施法这种处理,我需要单队列处理,那么threadmodel里面肯定只有一个MyThread  这样不算阻塞模式串行执行(或队列执行)把共享数据和线程临界区的问题也解决了不再依赖锁;

字很丑,请见谅

上面图片看出,在每一个threadmodel 里面都会两个队列,一个timertaskevent,一个是taskevent,会存在一个全局的timer thread;

全局的 timer thread 的作用是用来定时去处理和发现 threadmodel里面timertaskevent需要执行了,就把他加入到taskevent队里里面;最终执行是taskevent队列

timertaskevent为什么要存储在对应的threadmodel里面呢,那是因为比如,我A线程(threadmodel实例)运行一段时间后需要关闭,释放资源了,那么我还要去其他地方查找对应的timertask并移除掉;

 1 package net.sz.engine.thread;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 /**
 7  *
 8  * <br>
 9  * author 失足程序员<br>
10  * mail 492794628@qq.com<br>
11  * phone 13882122019<br>
12  */
13 class TimerThread extends Thread {
14 
15     private static final Object SYN_OBJECT = new Object();
16 
17     public TimerThread() {
18         super(ThreadPool.GloblThreadGroup, "Global Timer Thread");
19     }
20 
21     @Override
22     public void run() {
23         while (true) {
24             synchronized (SYN_OBJECT) {
25                 try {
26                     SYN_OBJECT.wait(2);
27                 } catch (InterruptedException ex) {
28                 }
29             }
30             HashMap<Long, ThreadModel> hashMap = new HashMap<>(ThreadPool.getThreadMap());
31             for (Map.Entry<Long, ThreadModel> entrySet : hashMap.entrySet()) {
32                 Long key = entrySet.getKey();
33                 ThreadModel value = entrySet.getValue();
34                 value.timerRun();
35             }
36         }
37     }
38 
39 }
View Code

线程模型的管理器

  1 package net.sz.engine.thread;
  2 
  3 import java.util.HashMap;
  4 import java.util.concurrent.ConcurrentHashMap;
  5 import net.sz.engine.script.manager.ScriptManager;
  6 import net.sz.engine.timer.GlobTimerEvent;
  7 import net.sz.engine.timer.PrintlnServerMemoryTimerEvent;
  8 import org.apache.log4j.Logger;
  9 
 10 /**
 11  * 线程管理器
 12  *
 13  * <br>
 14  * author 失足程序员<br>
 15  * mail 492794628@qq.com<br>
 16  * phone 13882122019<br>
 17  */
 18 public class ThreadPool {
 19 
 20     static private final Logger log = Logger.getLogger(ThreadPool.class);
 21     static public final long GloblThread;
 22     static private final TimerThread GloblTimerThread;
 23     static final long CheckThreadTimerThreadModel;
 24     static public final ThreadGroup GloblThreadGroup = new ThreadGroup("Global ThreadGroup");
 25     static public final ThreadGroup UnknownThreadGroup = new ThreadGroup(GloblThreadGroup, "Unknown ThreadGroup");
 26     static private final ConcurrentHashMap<Long, ThreadModel> threadMap = new ConcurrentHashMap<>();
 27 
 28     public static void main(String[] args) {
 29 
 30         ThreadPool.addTimerTask(GloblThread, new TimerTaskEvent(1000) {
 31 
 32             @Override
 33             public void run() {
 34 
 35                 log.error("ssssss");
 36             }
 37         });
 38     }
 39 
 40     static {
 41         //创建全局线程
 42         GloblThread = addThreadModel(GloblThreadGroup, "GloblThread");
 43         //执行指定任务定时触发脚步
 44         addTimerTask(GloblThread, new GlobTimerEvent(ScriptManager.getInstance().getBaseScriptEntry()));
 45         //查询服务器消耗定时模型
 46         addTimerTask(GloblThread, new PrintlnServerMemoryTimerEvent());
 47         //创建定时器线程
 48         GloblTimerThread = new TimerThread();
 49         GloblTimerThread.start();
 50         //检查线程卡死情况
 51         CheckThreadTimerThreadModel = addThreadModel(GloblThreadGroup, "Check Thread Timer Event");
 52         addTimerTask(CheckThreadTimerThreadModel, new CheckThreadTimerEvent());
 53     }
 54 
 55     /**
 56      * 删除指定id线程模型的时候回设置状态为停止状态
 57      *
 58      * @param tid
 59      * @return
 60      */
 61     static public ThreadModel remove(long tid) {
 62         ThreadModel remove = threadMap.remove(tid);
 63         if (remove != null) {
 64             remove.stop();
 65         }
 66         return remove;
 67     }
 68 
 69     /**
 70      * 获取线程池中所有线程
 71      *
 72      * @return
 73      */
 74     static public ConcurrentHashMap<Long, ThreadModel> getThreadMap() {
 75         return threadMap;
 76     }
 77 
 78     /**
 79      * 获取线程池的一个线程
 80      *
 81      * @param threadId
 82      * @return
 83      */
 84     static public ThreadModel getThreadModel(long threadId) {
 85         ThreadModel get = threadMap.get(threadId);
 86         if (get == null) {
 87             log.error("无法找到线程模型:" + threadId, new Exception("无法找到线程模型:" + threadId));
 88         }
 89         return get;
 90     }
 91 
 92     /**
 93      * 向线程池注册一个线程
 94      * <br>
 95      * 默认分组 UnknownThreadGroup
 96      *
 97      * @param name 线程名称
 98      * @return
 99      */
100     static public long addThreadModel(String name) {
101         return addThreadModel(UnknownThreadGroup, name);
102     }
103 
104     /**
105      * 向线程池注册一个线程
106      * <br>
107      * 默认分组 UnknownThreadGroup
108      *
109      * @param name 线程名称
110      * @param threadcount 线程量
111      * @return
112      */
113     static public long addThreadModel(String name, int threadcount) {
114         return addThreadModel(UnknownThreadGroup, name, threadcount);
115     }
116 
117     /**
118      * 向线程池注册一个线程
119      *
120      * @param group 线程分组信息
121      * @param name 线程名称
122      * @return
123      */
124     static public long addThreadModel(ThreadGroup group, String name) {
125         return addThreadModel(group, name, 1);
126     }
127 
128     /**
129      * 向线程池注册一个线程
130      *
131      * @param group 线程分组信息
132      * @param name 线程名称
133      * @param threadcount 线程量
134      * @return
135      */
136     static public long addThreadModel(ThreadGroup group, String name, int threadcount) {
137         return addThreadModel(group, name, null, threadcount);
138     }
139 
140     /**
141      * 向线程池注册一个线程
142      *
143      * @param group 线程分组信息
144      * @param name 线程名称
145      * @param runnable
146      * @param threadcount 线程量
147      * @return
148      */
149     static public long addThreadModel(ThreadGroup group, String name, Runnable runnable, int threadcount) {
150         ThreadModel threadModel = new ThreadModel(group, name, threadcount, runnable);
151         return addThreadModel(threadModel);
152     }
153 
154     /**
155      * 向线程池注册一个线程
156      *
157      * @param threadModel
158      */
159     static public long addThreadModel(ThreadModel threadModel) {
160         threadMap.put(threadModel.getId(), threadModel);
161         return threadModel.getId();
162     }
163 
164     /**
165      * 添加任务
166      *
167      * @param threadId
168      * @param task
169      * @return
170      */
171     static public boolean addTask(long threadId, TaskEvent task) {
172         ThreadModel threadModel = getThreadModel(threadId);
173         if (threadModel != null) {
174             threadModel.addTask(task);
175             return true;
176         }
177         return false;
178     }
179 
180     /**
181      * 添加定时器任务
182      *
183      * @param threadId
184      * @param task
185      * @return
186      */
187     static public boolean addTimerTask(long threadId, TimerTaskEvent task) {
188         ThreadModel threadModel = getThreadModel(threadId);
189         if (threadModel != null) {
190             threadModel.addTimer(task);
191             return true;
192         }
193         return false;
194     }
195 
196     /**
197      * 添加任务,添加任务到当前线程
198      *
199      * @param task
200      * @return
201      */
202     static public boolean addCurrentThreadTask(TaskEvent task) {
203         Thread currentThread = Thread.currentThread();
204         if (currentThread instanceof ThreadModel.MyThread) {
205             long threadId = currentThread.getId();
206             ThreadModel threadModel = getThreadModel(threadId);
207             if (threadModel != null) {
208                 threadModel.addTask(task);
209                 return true;
210             }
211         }
212         return false;
213     }
214 
215     /**
216      * 添加定时器任务,添加任务到当前线程
217      *
218      * @param task
219      * @return
220      */
221     static public boolean addCurrentThreadTimerTask(TimerTaskEvent task) {
222         Thread currentThread = Thread.currentThread();
223         if (currentThread instanceof ThreadModel.MyThread) {
224             long threadId = currentThread.getId();
225             ThreadModel threadModel = getThreadModel(threadId);
226             if (threadModel != null) {
227                 threadModel.addTimer(task);
228                 return true;
229             }
230         }
231         return false;
232     }
233 }
View Code

接下来我们看看使用情况

上篇文章中线程介绍代码

 1 public static void main(String[] args) throws InterruptedException {
 2         //线程并行情况,有多个线程执行多个任务/函数
 3         new Thread(new Run1()).start();
 4         new Thread(new Run2()).start();
 5     }
 6 
 7     //任务1
 8     static class Run1 implements Runnable {
 9 
10         @Override
11         public void run() {
12             //执行任务1
13             run1();
14             //执行任务3
15             run3();
16         }
17     }
18     //任务2
19 
20     static class Run2 implements Runnable {
21 
22         @Override
23         public void run() {
24             //执行任务3
25             run3();
26             //执行任务1
27             run1();
28             //执行任务2
29             run2();
30         }
31     }
32 
33     //任务1
34     public static void run1() {
35         System.out.println("run1()->" + System.currentTimeMillis());
36     }
37 
38     //任务2
39     public static void run2() {
40         System.out.println("run2()->" + System.currentTimeMillis());
41     }
42 
43     //任务3
44     public static void run3() {
45         System.out.println("run3()->" + System.currentTimeMillis());
46     }
View Code

我把代码切换模式

 1     public static void main(String[] args) throws InterruptedException {
 2         //线程并行情况,有多个线程执行多个任务/函数
 3 
 4         long test1 = ThreadPool.addThreadModel("测试线程-1");
 5         long test2 = ThreadPool.addThreadModel("测试线程-2");
 6         //添加任务
 7         ThreadPool.addTask(test1, new Run1());
 8         ThreadPool.addTask(test2, new Run2());
 9         //添加定时器任务
10         ThreadPool.addTimerTask(test1, new TimerRun1());
11         ThreadPool.addTimerTask(test2, new TimerRun2());
12 
13     }
14 
15     //任务1
16     static class Run1 extends TaskEvent {
17 
18         @Override
19         public void run() {
20             //执行任务1
21             run1();
22             //执行任务3
23             run3();
24         }
25     }
26 
27     //任务1
28     static class TimerRun1 extends TimerTaskEvent {
29 
30         public TimerRun1() {
31             super(500);//500毫秒无限制执行
32         }
33 
34         @Override
35         public void run() {
36             //执行任务1
37             run1();
38             //执行任务3
39             run3();
40         }
41     }
42 
43     //任务2
44     static class Run2 extends TaskEvent {
45 
46         @Override
47         public void run() {
48             //执行任务3
49             run3();
50             //执行任务1
51             run1();
52             //执行任务2
53             run2();
54         }
55     }
56 
57     //任务2
58     static class TimerRun2 extends TimerTaskEvent {
59 
60         public TimerRun2() {
61             super(500);//500毫秒无限制执行
62         }
63 
64         @Override
65         public void run() {
66             //执行任务3
67             run3();
68             //执行任务1
69             run1();
70             //执行任务2
71             run2();
72         }
73     }
74 
75     //任务1
76     public static void run1() {
77         System.out.println("run1()->" + System.currentTimeMillis());
78     }
79 
80     //任务2
81     public static void run2() {
82         System.out.println("run2()->" + System.currentTimeMillis());
83     }
84 
85     //任务3
86     public static void run3() {
87         System.out.println("run3()->" + System.currentTimeMillis());
88     }

接下来我们看看执行效果

run1()->1472120543013
run3()->1472120543013
run3()->1472120543017
run1()->1472120543017
run2()->1472120543017
run1()->1472120543517
run3()->1472120543517
run3()->1472120543517
run1()->1472120543517
run2()->1472120543517
run1()->1472120544018
run3()->1472120544018
run3()->1472120544018
run1()->1472120544018
run2()->1472120544018
run1()->1472120544520
run3()->1472120544520
run3()->1472120544520
run1()->1472120544520
run2()->1472120544520
run1()->1472120545021
run3()->1472120545021
run3()->1472120545021
run1()->1472120545021
run2()->1472120545021
run1()->1472120545521
run3()->1472120545521

 

一切正常;

这就是我的自定义线程模型;

到这里我的自定义线程模型就算介绍完成了;

那么优缺点在哪里呢?

优点是,数据流程控制很清晰,包括现在执行情况,以及线程卡死监控和任务 的定时器执行;

缺点,这个自定义线程模型依然不可能解决线程数据安全和临界区问题,在适当的时候依然需要靠锁或者其他形式来解决;

不足之处希望大神们指出,我好即时纠正。

 

posted on 2016-08-25 18:27  無心道(失足程序员)  阅读(936)  评论(6编辑  收藏  举报