当前位置: 代码迷 >> Java相关 >> Java 多线程 自定义线程匡扶
  详细解决方案

Java 多线程 自定义线程匡扶

热度:701   发布时间:2016-04-22 20:18:33.0
Java 多线程 自定义线程辅助

之前的文章我介绍了C#版本的多线程和自定义线程处理器。

接下来我们来看看Java版本的呢

java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的c++代码模拟线程,而C#的线程也是C++模拟线程。但是区别在于C#的线程会基于系统的线程。

C# 的 Thread.IsBackground;

这里唯一的区别在于,C#开启线程如果是非后台线程即便是你关闭了程序,如果不是强制退出进程的情况下。线程还会继续运行,知道垃圾回收机制强制回收。如果设置了后台线程标识,关闭程序就直接退出。

java没有一说。

java线程有分组和底层线程ID一说。C#没有。

java的线程可以自定义线程运行接口 Runnable 或者 重写线程run()方法。

其实这些都是大同小异的,区别性不大。

java线程的基础知识,到处都是,我不在BB

直接开始整体吧~!

  1 /**  2  * 线程模型  3  *  4  * @author 失足程序员  5  * @Blog http://www.cnblogs.com/ty408/  6  * @mail 492794628@qq.com  7  * @phone 13882122019  8  *  9  */ 10 public class ThreadModel extends Thread { 11  12     private static final Logger log = Logger.getLogger(TaskModel.class); 13     private static int threadID = 0; 14     private static final Object SYN_OBJECT = new Object(); 15     private long tid; 16     /** 17      * 任务列表 线程安全的任务列表 18      */ 19     protected final List<TaskModel> taskQueue = Collections.synchronizedList(new LinkedList<TaskModel>()); 20     //false标识删除线程 21     private boolean runing = true; 22  23     public ThreadModel(ThreadGroup group) { 24         this(group, "无名"); 25     } 26  27     public ThreadModel(ThreadGroup group, String name) { 28         super(group, name); 29         synchronized (SYN_OBJECT) { 30             threadID++; 31             tid = threadID; 32         } 33     } 34  35     @Override 36     public long getId() { 37         return this.tid; 38     } 39  40     /** 41      * 增加新的任务 每增加一个新任务,都要唤醒任务队列 42      * 43      * @param runnable 44      */ 45     public void addTask(TaskModel runnable) { 46         synchronized (taskQueue) { 47             taskQueue.add(runnable); 48             /* 唤醒队列, 开始执行 */ 49             taskQueue.notify(); 50         } 51     } 52  53     public void setRuning(boolean runing) { 54         this.runing = runing; 55     } 56  57     @Override 58     public void run() { 59         while (runing && ThreadManager.getInstance().isRunning()) { 60             TaskModel r = null; 61             while (taskQueue.isEmpty() && runing && ThreadManager.getInstance().isRunning()) { 62                 try { 63                     /* 任务队列为空,则等待有新任务加入从而被唤醒 */ 64                     synchronized (taskQueue) { 65                         taskQueue.wait(500); 66                     } 67                 } catch (InterruptedException ie) { 68                     log.error(ie); 69                 } 70             } 71             synchronized (taskQueue) { 72                 /* 取出任务执行 */ 73                 if (runing && ThreadManager.getInstance().isRunning()) { 74                     r = taskQueue.remove(0); 75                 } 76             } 77             if (r != null) { 78                 /* 执行任务 */ 79                 //r.setSubmitTimeL(); 80                 long submitTime = System.currentTimeMillis(); 81                 try { 82                     r.run(); 83                 } catch (Exception e) { 84                     log.error("工人<“" + Thread.currentThread().getName() + "”> 执行任务<" + r.getID() + "(“" + r.getName() + "”)> 遇到错误: " + e); 85                     e.printStackTrace(); 86                 } 87                 long timeL1 = System.currentTimeMillis() - submitTime; 88                 long timeL2 = System.currentTimeMillis() - r.getSubmitTime(); 89                 if (timeL1 <= 100L) { 90                     log.info("工人<“" + Thread.currentThread().getName() + "”> 完成了任务:" + r.toString() + " 执行耗时:" + timeL1 + " 提交耗时:" + timeL2); 91                 } else if (timeL1 <= 1000L) { 92                     log.info("工人<“" + Thread.currentThread().getName() + "”> 长时间执行 完成任务:" + r.toString() + " “考虑”任务脚本逻辑 耗时:" + timeL1 + " 提交耗时:" + timeL2); 93                 } else if (timeL1 <= 4000L) { 94                     log.info("工人<“" + Thread.currentThread().getName() + "”> 超长时间执行完成 任务:" + r.toString() + " “检查”任务脚本逻辑 耗时:" + timeL1 + " 提交耗时:" + timeL2); 95                 } else { 96                     log.info("工人<“" + Thread.currentThread().getName() + "”> 超长时间执行完成 任务:" + r.toString() + " “考虑是否应该删除”任务脚本 耗时:" + timeL1 + " 提交耗时:" + timeL2); 97                 } 98                 r = null; 99             }100         }101         log.error("线程结束, 工人<“" + Thread.currentThread().getName() + "”>退出");102     }103 104     @Override105     public String toString() {106         return "Thread{" + "tid=" + tid + ",Name=" + this.getName() + '}';107     }108 109 }

这里创建我们自定义的线程模型,有两点值得注意的是,

protected final List<TaskModel> taskQueue = Collections.synchronizedList(new LinkedList<TaskModel>());
synchronized (taskQueue) {            taskQueue.add(runnable);            /* 唤醒队列, 开始执行 */            taskQueue.notify();        }synchronized (taskQueue) {                        taskQueue.wait(500);                    }

这里我们同样没有使用Thread.Sleep();对线程进行暂停,同样使用的是 taskQueue.wait();来进行线程暂停,这是因为当任务队列为空的时候,需要暂停线程。

当新的任务被放进来的时候,又必须立即开始执行任务。

为了防止线程永久暂停,设置的是500毫秒,这样我们需要关闭程序(ThreadManager.getInstance().isRunning()==false)停止线程时候他会自定停止。

辅助键值对存储器

  1 /**  2  * 辅助键值对存储  3  *  4  * @author 失足程序员  5  * @Blog http://www.cnblogs.com/ty408/  6  * @mail 492794628@qq.com  7  * @phone 13882122019  8  */  9 public class ObjectAttribute extends HashMap<String, Object> { 10  11     private static final long serialVersionUID = -5320260807959251398L; 12  13     /** 14      * 调用此方法 删除值是需要保证存在key值和value值 否则空指针报错 15      * 16      * @param <T> 17      * @param key 18      * @param clazz 19      * @return 20      * @deprecated 需要保证存在key值和value值 否则空指针报错 慎重 21      */ 22     @Deprecated 23     public <T extends Object> T remove(String key, Class<T> clazz) { 24         Object obj = this.remove(key); 25         return (T) obj; 26     } 27  28     /** 29      * 如果未找到也返回 null 30      * 31      * @param key 32      * @return 33      */ 34     public String getStringValue(String key) { 35         if (this.containsKey(key)) { 36             return this.get(key).toString(); 37         } 38         return null; 39     } 40  41     /** 42      * 如果未找到也返回 0 43      * 44      * @param key 45      * @return 46      */ 47     public int getintValue(String key) { 48         if (this.containsKey(key)) { 49             return (int) (this.get(key)); 50         } 51         return 0; 52     } 53  54     /** 55      * 如果未找到也返回 null 56      * 57      * @param key 58      * @return 59      */ 60     public Integer getIntegerValue(String key) { 61         if (this.containsKey(key)) { 62             return (Integer) (this.get(key)); 63         } 64         return null; 65     } 66  67     /** 68      * 如果未找到也返回 0 69      * 70      * @param key 71      * @return 72      */ 73     public long getlongValue(String key) { 74         if (this.containsKey(key)) { 75             return (long) (this.get(key)); 76         } 77         return 0; 78     } 79  80     /** 81      * 如果未找到也返回 null 82      * 83      * @param key 84      * @return 85      */ 86     public Long getLongValue(String key) { 87         if (this.containsKey(key)) { 88             return (Long) (this.get(key)); 89         } 90         return null; 91     } 92  93     /** 94      * 如果未找到也返回 0 95      * 96      * @param key 97      * @return 98      */ 99     public float getfloatValue(String key) {100         if (this.containsKey(key)) {101             return (float) (this.get(key));102         }103         return 0;104     }105 106     /**107      * 如果未找到也返回 null108      *109      * @param key110      * @return111      */112     public Float getFloatValue(String key) {113         if (this.containsKey(key)) {114             return (Float) (this.get(key));115         }116         return null;117     }118 119     /**120      * 如果未找到也返回 false121      *122      * @param key123      * @return124      */125     public boolean getbooleanValue(String key) {126         if (this.containsKey(key)) {127             return (boolean) (this.get(key));128         }129         return false;130     }131 132     /**133      * 如果未找到也返回 null134      *135      * @param key136      * @return137      */138     public Boolean getBooleanValue(String key) {139         if (this.containsKey(key)) {140             return (Boolean) (this.get(key));141         }142         return null;143     }144 145     @Override146     public Object clone() {147         return super.clone(); //To change body of generated methods, choose Tools | Templates.148     }149 }
View Code

 

任务执行模型

 1 /** 2  * 任务模型 3  * 4  * @author 失足程序员 5  * @Blog http://www.cnblogs.com/ty408/ 6  * @mail 492794628@qq.com 7  * @phone 13882122019 8  * 9  */10 public abstract class TaskModel {11 12     private static final Logger log = Logger.getLogger(TaskModel.class);13 14     private long ID;15     private String Name;16     //运行时数据17     private ObjectAttribute runAttribute = new ObjectAttribute();18 19     public TaskModel(long ID, String Name) {20         this.ID = ID;21         this.Name = Name;22         this.runAttribute.put("submitTime", System.currentTimeMillis());23     }24 25     public TaskModel() {26         this(0, "无名");27     }28 29     public long getSubmitTime() {30         return this.runAttribute.getlongValue("submitTime");31     }32 33     public ObjectAttribute getRunAttribute() {34         return runAttribute;35     }36 37     public void setRunAttribute(ObjectAttribute runAttribute) {38         this.runAttribute = runAttribute;39     }40 41     public long getID() {42         return ID;43     }44 45     public String getName() {46         return Name;47     }48 49     public abstract void run();50 51     @Override52     public String toString() {53         return "TaskModel{" + "ID=" + ID + ", Name=" + Name + ", runAttribute=" + runAttribute + '}';54     }55 56 }

 

接下来我们测试一下

1   ThreadModel threadModel = new ThreadModel(new ThreadGroup("Test"), "Test");2         threadModel.start();3         threadModel.addTask(new TaskModel() {4 5             @Override6             public void run() {7                 System.out.println("TaskModel Test");8             }9         });

执行结果

TaskModel Test[04-24 17:31:26:0223:INFO : sz.network.threadpool.TaskModel:97 行] -> 工人<“Test”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={submitTime=1429867886219}} 执行耗时:0 提交耗时:4

我们看到居然有提交耗时,,别奇怪,,因为在某些情况下,线程的从暂停状态到唤醒状态需要消耗时间的,系统不可能有那么多空闲资源,收到你的命令马上就放弃一切事情执行你的命令。

我们调试运行时可以看见当前程序所有线程,以及分组情况(我使用的是NetBeans IDE 8.0.2 开发工具)

 

接下来我们来构建一下。后台线程池,

 1 /** 2  * 后台线程池 3  * 4  * @author 失足程序员 5  * @Blog http://www.cnblogs.com/ty408/ 6  * @mail 492794628@qq.com 7  * @phone 13882122019 8  */ 9 class BackThread {10 11     private static final Logger log = Logger.getLogger(BackThread.class);12 13     private final ThreadGroup threadGroup = new ThreadGroup(ThreadManager.getGlobeThreadGroup(), "后台执行器");14 15     /* 任务列表 */16     private final List<TaskModel> taskQueue = Collections.synchronizedList(new LinkedList<TaskModel>());17     private final BackThreadRunnable backThreadRunnable = new BackThreadRunnable();18 19     public BackThread() {20         int threadcountI = 10;21         for (int i = 1; i <= threadcountI; i++) {22             Thread thread = new Thread(threadGroup, backThreadRunnable, "后台线程-" + i);23             thread.start();24         }25         log.info("---初始化后台线程池--线程数量:" + threadcountI + "------------");26     }27 28     /**29      * 增加新的任务 每增加一个新任务,都要唤醒任务队列30      *31      * @param newTask32      */33     public void addTask(TaskModel newTask) {34         synchronized (taskQueue) {35             taskQueue.add(newTask);36             /* 唤醒队列, 开始执行 */37             taskQueue.notify();38         }39     }40 41     final class BackThreadRunnable implements Runnable {42 43         /**44          * 循环执行任务45          */46         @Override47         public void run() {48             while (ThreadManager.getInstance().isRunning()) {49                 TaskModel r = null;50                 synchronized (taskQueue) {51                     while (taskQueue.isEmpty() && ThreadManager.getInstance().isRunning()) {52                         try {53                             /* 任务队列为空,则等待有新任务加入从而被唤醒 */54                             taskQueue.wait(500);55                         } catch (InterruptedException ie) {56                             log.error(ie);57                         }58                     }59                     /* 取出任务执行 */60                     if (ThreadManager.getInstance().isRunning()) {61                         r = taskQueue.remove(0);62                     }63                 }64                 if (r != null) {65                     /* 执行任务 */66                     //r.setSubmitTimeL();67                     long submitTime = System.currentTimeMillis();68                     try {69                         r.run();70                     } catch (Exception e) {71                         e.printStackTrace();72                         log.error("工人<“" + Thread.currentThread().getName() + "”> 执行任务<" + r.getID() + "(“" + r.getName() + "”)> 遇到错误: " + e);73                     }74                     long timeL1 = System.currentTimeMillis() - submitTime;75                     long timeL2 = System.currentTimeMillis() - r.getSubmitTime();76                     if (timeL1 <= 100L) {77                         log.info("工人<“" + Thread.currentThread().getName() + "”> 完成了任务:" + r.toString() + " 执行耗时:" + timeL1 + " 提交耗时:" + timeL2);78                     } else if (timeL1 <= 1000L) {79                         log.info("工人<“" + Thread.currentThread().getName() + "”> 长时间执行 完成任务:" + r.toString() + " “考虑”任务脚本逻辑 耗时:" + timeL1 + " 提交耗时:" + timeL2);80                     } else if (timeL1 <= 4000L) {81                         log.info("工人<“" + Thread.currentThread().getName() + "”> 超长时间执行完成 任务:" + r.toString() + " “检查”任务脚本逻辑 耗时:" + timeL1 + " 提交耗时:" + timeL2);82                     } else {83                         log.info("工人<“" + Thread.currentThread().getName() + "”> 超长时间执行完成 任务:" + r.toString() + " “考虑是否应该删除”任务脚本 耗时:" + timeL1 + " 提交耗时:" + timeL2);84                     }85                     r = null;86                 }87             }88             log.error("线程结束, 工人<“" + Thread.currentThread().getName() + "”>退出");89         }90     }91 }

 

以及定时器线程处理器

 1 /** 2  * 定时器线程 3  * 4  * @author 失足程序员 5  * @Blog http://www.cnblogs.com/ty408/ 6  * @mail 492794628@qq.com 7  * @phone 13882122019 8  */ 9 class TimerThread extends ThreadModel {10 11     private static final Logger log = Logger.getLogger(TimerThread.class);12 13     public TimerThread() {14         super(ThreadManager.getGlobeThreadGroup(), "全局定时器线程");15         this.start();16     }17 18     @Override19     public void run() {20         while (ThreadManager.getInstance().isRunning()) {21             while (ThreadManager.getInstance().isRunning() && taskQueue.isEmpty()) {22                 try {23                     /* 任务队列为空,则等待有新任务加入从而被唤醒 */24                     synchronized (taskQueue) {25                         taskQueue.wait(200);26                     }27                 } catch (InterruptedException ie) {28                 }29             }30             ArrayList<TaskModel> taskModels;31             synchronized (taskQueue) {32                 //队列不为空的情况下  取出队列定时器任务33                 taskModels = new ArrayList<>(taskQueue);34             }35             if (!taskModels.isEmpty()) {36                 for (TaskModel task : taskModels) {37                     TimerTask timerEvent = (TimerTask) task;38                     int execCount = timerEvent.getRunAttribute().getintValue("Execcount");39                     long lastTime = timerEvent.getRunAttribute().getlongValue("LastExecTime");40                     long nowTime = System.currentTimeMillis();41                     if (nowTime > timerEvent.getStartTime() //是否满足开始时间42                             && (nowTime - timerEvent.getSubmitTime() > timerEvent.getIntervalTime())//提交以后是否满足了间隔时间43                             && (timerEvent.getEndTime() <= 0 || nowTime < timerEvent.getEndTime()) //判断结束时间44                             && (nowTime - lastTime >= timerEvent.getIntervalTime())) //判断上次执行到目前是否满足间隔时间45                     {46                         //提交执行47                         ThreadManager.getInstance().addTask(timerEvent.gettID(), timerEvent);48                         //记录49                         execCount++;50                         timerEvent.getRunAttribute().put("Execcount", execCount);51                         timerEvent.getRunAttribute().put("LastExecTime", nowTime);52                     }53                     nowTime = System.currentTimeMillis();54                     //判断删除条件55                     if ((timerEvent.getEndTime() > 0 && nowTime < timerEvent.getEndTime())56                             || (timerEvent.getActionCount() > 0 && timerEvent.getActionCount() <= execCount)) {57                         taskQueue.remove(task);58                     }59                 }60             }61             try {62                 //定时器, 执行方式 间隔 4ms 执行一次 把需要处理的任务放到对应的处理线程63                 Thread.sleep(4);64             } catch (InterruptedException ex) {65             }66         }67         log.error("线程结束, 工人<“" + Thread.currentThread().getName() + "”>退出");68     }69 70     @Override71     public void addTask(TaskModel task) {72         if (((TimerTask) task).isIsStartAction()) {73             try {74                 task.run();75             } catch (Exception e) {76                 log.error("工人<“" + Thread.currentThread().getName() + "”> 执行任务<" + task.getID() + "(“" + task.getName() + "”)> 遇到错误: " + e);77                 e.printStackTrace();78             }79         }80         super.addTask(task);81     }82 }

 

定时器线程执行任务模型

  1 /**  2  * 定时器执行器  3  *  4  * @author 失足程序员  5  * @Blog http://www.cnblogs.com/ty408/  6  * @mail 492794628@qq.com  7  * @phone 13882122019  8  */  9 public abstract class TimerTask extends TaskModel { 10  11     private static final long serialVersionUID = -8331296295264699207L; 12  13     /** 14      * 线程ID 15      */ 16     private long tID; 17     /** 18      * 开始执行的时间 19      */ 20     private long startTime; 21  22     /** 23      * 是否一开始执行一次 24      */ 25     private boolean isStartAction; 26  27     /** 28      * 结束时间 29      */ 30     private long endTime; 31  32     /** 33      * 执行次数 34      */ 35     private int actionCount; 36  37     /** 38      * 间隔执行时间 39      */ 40     private int intervalTime; 41  42     /** 43      * 44      * @param tID 指定执行线程 45      * @param startTime 指定开始时间 46      * @param isStartAction 是否一开始就执行一次 47      * @param endTime 指定结束时间 48      * @param actionCount 指定执行次数 49      * @param intervalTime 指定间隔时间 50      * @param ID 51      * @param Name 52      */ 53     public TimerTask(long tID, long startTime, boolean isStartAction, long endTime, int actionCount, int intervalTime, long ID, String Name) { 54         super(ID, Name); 55         this.tID = tID; 56         this.startTime = startTime; 57         this.isStartAction = isStartAction; 58         this.endTime = endTime; 59         this.actionCount = actionCount; 60         this.intervalTime = intervalTime; 61     } 62  63     /** 64      * 指定任务的开始执行时间 65      * 66      * @param tID 指定执行线程 67      * @param startTime 指定开始时间 68      * @param isStartAction 是否一开始就执行一次 69      * @param actionCount 指定执行次数 70      * @param intervalTime 指定间隔时间 71      * @param ID 72      * @param Name 73      */ 74     public TimerTask(long tID, long startTime, boolean isStartAction, int actionCount, int intervalTime, long ID, String Name) { 75         this(tID, startTime, isStartAction, 0, actionCount, intervalTime, ID, Name); 76     } 77  78     /** 79      * 指定结束时间已结束时间为准,执行次数不一定够 80      * 81      * @param tID 指定执行线程 82      * @param isStartAction 是否一开始就执行一次 83      * @param endTime 指定结束时间 84      * @param actionCount 指定执行次数 85      * @param intervalTime 指定间隔时间 86      * @param ID 87      * @param Name 88      */ 89     public TimerTask(long tID, boolean isStartAction, long endTime, int actionCount, int intervalTime, long ID, String Name) { 90         this(tID, 0, isStartAction, endTime, actionCount, intervalTime, ID, Name); 91     } 92  93     /** 94      * 指定开始时间,和结束时间 95      * 96      * @param tID 指定执行线程 97      * @param startTime 指定开始时间 98      * @param endTime 指定结束时间 99      * @param intervalTime 指定间隔时间100      * @param ID101      * @param Name102      */103     public TimerTask(long tID, long startTime, long endTime, int intervalTime, long ID, String Name) {104         this(tID, startTime, false, endTime, -1, intervalTime, ID, Name);105     }106 107     /**108      * 指定执行线程,指定执行次数,指定间隔时间109      *110      * @param tID 指定执行线程111      * @param actionCount 指定执行次数112      * @param intervalTime 指定间隔时间113      * @param ID114      * @param Name115      */116     public TimerTask(long tID, int actionCount, int intervalTime, long ID, String Name) {117         this(tID, 0, false, 0, actionCount, intervalTime, ID, Name);118     }119 120     /**121      * 指定的执行次数和间隔时间122      *123      * @param actionCount 指定执行次数124      * @param intervalTime 指定间隔时间125      */126     public TimerTask(int actionCount, int intervalTime) {127         this(0, 0, false, 0, actionCount, intervalTime, 0, "无名");128     }129 130     /**131      * 提交后指定的时间以后执行一次132      *133      * @param intervalTime 指定间隔时间134      */135     public TimerTask(int intervalTime) {136         this(0, 0, false, 0, 1, intervalTime, 0, "无名");137     }138 139     public long gettID() {140         return tID;141     }142 143     public void settID(long tID) {144         this.tID = tID;145     }146 147     public long getStartTime() {148         return startTime;149     }150 151     public void setStartTime(long startTime) {152         this.startTime = startTime;153     }154 155     public boolean isIsStartAction() {156         return isStartAction;157     }158 159     public void setIsStartAction(boolean isStartAction) {160         this.isStartAction = isStartAction;161     }162 163     public long getEndTime() {164         return endTime;165     }166 167     public void setEndTime(long endTime) {168         this.endTime = endTime;169     }170 171     public int getActionCount() {172         return actionCount;173     }174 175     public void setActionCount(int actionCount) {176         this.actionCount = actionCount;177     }178 179     public int getIntervalTime() {180         return intervalTime;181     }182 183     public void setIntervalTime(int intervalTime) {184         this.intervalTime = intervalTime;185     }186 187 }

 

创建一个线程管理器

 1 /** 2  * 线程管理器 3  * 4  * @author 失足程序员 5  * @Blog http://www.cnblogs.com/ty408/ 6  * @mail 492794628@qq.com 7  * @phone 13882122019 8  * 9  */10 public class ThreadManager {11 12     private static final Logger log = Logger.getLogger(ThreadManager.class);13 14     private static final ThreadGroup GlobeThreadGroup = new ThreadGroup("全局线程");15     private static final ThreadGroup lsThreadGroup = new ThreadGroup("零时线程");16 17     private static ThreadManager instance = new ThreadManager();18 19     private static final HashMap<Long, ThreadModel> workThreadMaps = new HashMap<>(0);20 21     public static ThreadManager getInstance() {22         return instance;23     }24 25     public static ThreadGroup getGlobeThreadGroup() {26         return GlobeThreadGroup;27     }28 29     private final BackThread backThread = new BackThread();30 31     private final TimerThread timerThread = new TimerThread();32 33     //服务器是否运行状态标识34     private boolean running = true;35 36     public boolean isRunning() {37         return running;38     }39 40     public void StopServer() {41         running = false;42     }43 44     public long addThread(ThreadModel thread) {45         workThreadMaps.put(thread.getId(), thread);46         thread.start();47         return thread.getId();48     }49 50     public long getThread(ThreadGroup threadGroup, String workName) {51         return addThread(new ThreadModel(threadGroup, workName));52     }53 54     public long getThread(String workName) {55         return addThread(new ThreadModel(lsThreadGroup, workName));56     }57 58     public boolean delete(long threadID) {59         ThreadModel get = workThreadMaps.remove(threadID);60         if (get != null) {61             get.setRuning(false);62             return true;63         }64         return false;65     }66 67     public void addTask(long threadID, TaskModel task) {68         if (workThreadMaps.containsKey(threadID)) {69             workThreadMaps.get(threadID).addTask(task);70         } else {71             addBackTask(task);72         }73     }74 75     public void addTimerTask(TimerTask task) {76         timerThread.addTask(task);77     }78 79     /**80      *81      * @param task82      */83     public void addBackTask(TaskModel task) {84         backThread.addTask(task);85     }86 87 }
View Code

重新测试一下

 1 public static void main(String[] args) { 2  3         long thread = ThreadManager.getInstance().getThread("Test"); 4         ThreadManager.getInstance().addBackTask(new TaskModel() { 5  6             @Override 7             public void run() { 8                 System.out.println("addBackTask"); 9             }10         });11         ThreadManager.getInstance().addTimerTask(new TimerTask(5, 100) {12 13             @Override14             public void run() {15                 System.out.println("TimerTask 5 100");16             }17         });18         ThreadManager.getInstance().addTask(thread, new TaskModel() {19 20             @Override21             public void run() {22                 System.out.println("Thread test");23             }24         });25     }

 

 1 [04-24 17:40:23:0883:INFO : sz.network.threadpool.BackThread:37 行] -> ---初始化后台线程池--线程数量:10------------ 2 addBackTask 3 Thread test 4 [04-24 17:40:23:0888:INFO : sz.network.threadpool.BackThread:89 行] -> 工人<“后台线程-10”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={submitTime=1429868423887}} 执行耗时:0 提交耗时:0 5 [04-24 17:40:23:0888:INFO : sz.network.threadpool.TaskModel:97 行] -> 工人<“Test”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={submitTime=1429868423887}} 执行耗时:1 提交耗时:1 6 TimerTask 5 100 7 [04-24 17:40:23:0988:INFO : sz.network.threadpool.BackThread:89 行] -> 工人<“后台线程-9”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={LastExecTime=1429868423988, submitTime=1429868423887, Execcount=1}} 执行耗时:0 提交耗时:101 8 TimerTask 5 100 9 [04-24 17:40:24:0088:INFO : sz.network.threadpool.BackThread:89 行] -> 工人<“后台线程-8”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={LastExecTime=1429868424088, submitTime=1429868423887, Execcount=2}} 执行耗时:0 提交耗时:20110 TimerTask 5 10011 [04-24 17:40:24:0189:INFO : sz.network.threadpool.BackThread:89 行] -> 工人<“后台线程-7”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={LastExecTime=1429868424189, submitTime=1429868423887, Execcount=3}} 执行耗时:0 提交耗时:30212 TimerTask 5 10013 [04-24 17:40:24:0289:INFO : sz.network.threadpool.BackThread:89 行] -> 工人<“后台线程-6”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={LastExecTime=1429868424289, submitTime=1429868423887, Execcount=4}} 执行耗时:0 提交耗时:40214 TimerTask 5 10015 [04-24 17:40:24:0389:INFO : sz.network.threadpool.BackThread:89 行] -> 工人<“后台线程-9”> 完成了任务:TaskModel{ID=0, Name=无名, runAttribute={LastExecTime=1429868424389, submitTime=1429868423887, Execcount=5}} 执行耗时:0 提交耗时:502

调试查看线程信息

Java版本的自定义线程处理器就算完成了。

功能和实现基本和C#版本一样。

 

C# 线程系列三 定时器线程

c# 多线程系列二 自定义线程执行器

 

1楼digdeep
看到第一个例子时,感觉写得有点小问题...,,getId() 要加锁synchronized (SYN_OBJECT),,taskQueue 既然被sychronized保护了,就没有必要使用Collections.synchronizedList来包装了
Re: 失足程序员
@digdeep,引用看到第一个例子时,感觉写得有点小问题...,,getId() 要加锁synchronized (SYN_OBJECT),,taskQueue 既然被sychronized保护了,就没有必要使用Collections.synchronizedList来包装了,getID()是get属性而已,无需加锁,taskQueue 使用Collections.synchronizedList 包装,包装线程安全的,sychronized锁的意义其实在于线程的暂停和唤醒,必须要加锁才行,不然是要抛错的
  相关解决方案