zoukankan      html  css  js  c++  java
  • 看我是如何处理自定义线程模型---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
        ")
    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("
        ")
    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("
    ++++++++++++++++++++++++++++++++++");
    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

    一切正常;

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

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

    那么优缺点在哪里呢?

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

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

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

  • 相关阅读:
    D
    洛谷P2002 消息扩散
    洛谷P5058 [ZJOI2004]嗅探器
    洛谷P2746 校园网Network of Schools
    洛谷P3388 【模板】割点(割顶)
    洛谷P1407 [国家集训队]稳定婚姻
    2018年12月18日
    洛谷P1547 Out of Hay
    洛谷P4018 Roy&October之取石子
    洛谷P1318 积水面积
  • 原文地址:https://www.cnblogs.com/shizuchengxuyuan/p/5807732.html
Copyright © 2011-2022 走看看