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 [email protected]
  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     @Override
105     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 [email protected]
  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      * 如果未找到也返回 null
108      *
109      * @param key
110      * @return
111      */
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      * 如果未找到也返回 false
121      *
122      * @param key
123      * @return
124      */
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      * 如果未找到也返回 null
134      *
135      * @param key
136      * @return
137      */
138     public Boolean getBooleanValue(String key) {
139         if (this.containsKey(key)) {
140             return (Boolean) (this.get(key));
141         }
142         return null;
143     }
144
145     @Override
146     public Object clone() {
147         return super.clone(); //To change body of generated methods, choose Tools | Templates.
148     }
149 }

任务执行模型

 1 /**
 2  * 任务模型
 3  *
 4  * @author 失足程序员
 5  * @Blog http://www.cnblogs.com/ty408/
 6  * @mail [email protected]q.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     @Override
52     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             @Override
6             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 [email protected]
 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 newTask
32      */
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         @Override
47         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 [email protected]
 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     @Override
19     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     @Override
71     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 [email protected]
  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 ID
101      * @param Name
102      */
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 ID
114      * @param Name
115      */
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 [email protected]
 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 task
82      */
83     public void addBackTask(TaskModel task) {
84         backThread.addTask(task);
85     }
86
87 }

重新测试一下

 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             @Override
14             public void run() {
15                 System.out.println("TimerTask 5 100");
16             }
17         });
18         ThreadManager.getInstance().addTask(thread, new TaskModel() {
19
20             @Override
21             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 提交耗时:201
10 TimerTask 5 100
11 [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 提交耗时:302
12 TimerTask 5 100
13 [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 提交耗时:402
14 TimerTask 5 100
15 [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# 多线程系列二 自定义线程执行器

时间: 2024-10-30 08:25:16

Java 多线程 自定义线程辅助的相关文章

Java多线程之线程结束清理

该事例说明了清理工作必须要放在finally块中 package Thread.Interrupting; import java.util.concurrent.TimeUnit; class NeedsCleanup { private final int id; public NeedsCleanup(int ident) { id = ident; System.out.println("NeedsCleanup " + id); } public void cleanup()

Java多线程之线程中断

该例子说明,Sleep可以被中断,但是I/O和synchronized不能被中断. package Thread.Interrupting; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; imp

java多线程之线程的同步与锁定(转)

一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. publicclass Foo { privateint x = 100; publicint getX() { return x;     } publicint fix(int y) {         x = x - y; return x;     } } publicclass MyRunnable i

java多线程之 ---- 线程死锁

java多线程之线程死锁 产生死锁的主要原因: 因为系统资源不足. 进程运行推进的顺序不合适. 资源分配不当等. 如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁.其次, 进程运行推进顺序与速度不同,也可能产生死锁. 产生死锁的四个必要条件:  互斥条件:一个资源每次只能被一个进程使用. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放. 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺. 循环等待条件:若干进

java多线程之 ---- 线程同步

java多线程之线程同步 线程同步 定义:同步是指在同一时间段内只能运行一个线程. 分类:同步方法.同步块. 作用:安全解决共享问题. 同步块: 语法: synchronized (同步对象) { 需要同步的代码; } 例子: public class ThreadDemo implements Runnable{ private int ticket = 5; public void run(){ for(int i=1;i<=5;i++){ synchronized (this){ if(t

JAVA多线程之线程间的通信方式

一,介绍 本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码. 二,线程间的通信方式 ①同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. 参考示例: public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB()

Java多线程之线程的同步

Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同一个数据时,非常容易出现线程安全问题.具体原因如下:   1,多个线程同时访问一个数据资源(该资源称为临界资源),形成数据发生不一致和不完整.   2,数据的不一致往往是因为一个线程中的多个关联的操作(这几个操作合成原子操作)未全部完成. 关于线程安全问题,有一个经典的情景:银行取钱.代码如下: /

Java多线程之线程的控制

Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dead 如果将"锁池"和"等待队列"都看成是"阻塞"状态的特殊情况,那么可以将线程归纳为5个状态: 新建,就绪,运行,阻塞,死亡. ┌--------------------< 阻塞 ↓                    (1)(2)(3)  

Java多线程之线程的通信

Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些线程中哪个线程拿到锁标记由系统决定.前面我们也有T到死锁的概念,线程互相等待其他线程释放锁标记,而又不释放自己的:造成无休止地等待.当出现死锁的时候,我们应该如何解决呢?通过线程间的通信解决. 线程间通信: 多线程之间的通信有2种方式,第一种是使用object类的几个方法,第二种是使用条件变了来控制