java自定义线程模型处理方法分享

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

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

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

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

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

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

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

package net.sz.engine.thread;

import java.io.Serializable;
import org.apache.log4j.Logger;
import net.sz.engine.structs.ObjectAttribute;
import net.sz.engine.structs.ObjectGlobal;

/**
 * 任务模型
 *
 * <br>
 * author 失足程序员<br>
 * mail 492794628@qq.com<br>
 * phone 13882122019<br>
 */
public abstract class TaskEvent implements Serializable, Cloneable {

 private static final Logger log = Logger.getLogger(TaskEvent.class);
 private static final long serialVersionUID = 4196020659994845804L;

 //运行时数据
 private transient final ObjectAttribute runOther = new ObjectAttribute;
 //任务创建的时间
 protected long createTime;
 //任务的唯一id
 protected long taskId;
 //取消的任务
 protected boolean cancel = false;

 public TaskEvent {
  this.runOther.put("submitTime", System.currentTimeMillis);
  createTime = System.currentTimeMillis;
  cancel = false;
  taskId = ObjectGlobal.getUUID;
 }

 public long getCreateTime {
  return createTime;
 }

 public void setCreateTime(long createTime) {
  this.createTime = createTime;
 }

 public long getSubmitTime {
  return this.runOther.getlongValue("submitTime");
 }

 public ObjectAttribute getRunOther {
  return runOther;
 }

 public boolean isCancel {
  return cancel;
 }

 public void setCancel(boolean cancel) {
  this.cancel = cancel;
 }

 public abstract void run;

 @Override
 public Object clone throws CloneNotSupportedException {
  return super.clone; //To change body of generated methods, choose Tools | Templates.
 }

}
package net.sz.engine.thread;

/**
 * 定时器执行器
 *
 * <br>
 * author 失足程序员<br>
 * mail 492794628@qq.com<br>
 * phone 13882122019<br>
 */
public abstract class TimerTaskEvent extends TaskEvent {

 private static final long serialVersionUID = -8331296295264699207L;

 /**
  * 开始执行的时间
  */
 protected long startTime;

 /**
  * 是否一开始执行一次
  */
 protected boolean startAction;

 /**
  * 结束时间
  */
 protected long endTime;

 /**
  * 执行次数
  */
 protected int actionCount;

 /**
  * 间隔执行时间
  */
 protected int intervalTime;

 /**
  *
  * @param startTime 指定开始时间
  * @param isStartAction 是否一开始就执行一次
  * @param endTime 指定结束时间
  * @param actionCount 指定执行次数
  * @param intervalTime 指定间隔时间
  */
 public TimerTaskEvent(long startTime, boolean isStartAction, long endTime, int actionCount, int intervalTime) {
  super;
  this.startTime = startTime;
  this.startAction = isStartAction;
  this.endTime = endTime;
  this.actionCount = actionCount;
  this.intervalTime = intervalTime;
 }

 /**
  * 指定任务的开始执行时间
  *
  * @param startTime 指定开始时间
  * @param isStartAction 是否一开始就执行一次
  * @param actionCount 指定执行次数
  * @param intervalTime 指定间隔时间
  */
 public TimerTaskEvent(long startTime, boolean isStartAction, int actionCount, int intervalTime) {
  this(startTime, isStartAction, 0, actionCount, intervalTime);
 }

 /**
  * 指定结束时间已结束时间为准,执行次数不一定够
  *
  * @param isStartAction 是否一开始就执行一次
  * @param endTime 指定结束时间
  * @param actionCount 指定执行次数
  * @param intervalTime 指定间隔时间
  *
  */
 public TimerTaskEvent(boolean isStartAction, long endTime, int actionCount, int intervalTime) {
  this(0, isStartAction, endTime, actionCount, intervalTime);
 }

 /**
  * 指定开始时间,和结束时间
  *
  * @param startTime 指定开始时间
  * @param endTime 指定结束时间
  * @param intervalTime 指定间隔时间
  */
 public TimerTaskEvent(long startTime, long endTime, int intervalTime) {
  this(startTime, false, endTime, -1, intervalTime);
 }

 /**
  * 指定的执行次数和间隔时间
  *
  * @param actionCount 指定执行次数
  * @param intervalTime 指定间隔时间
  */
 public TimerTaskEvent(int actionCount, int intervalTime) {
  this(0, false, 0, actionCount, intervalTime);
 }

 /**
  * 提交后指定的时间无限制执行
  *
  * @param intervalTime 指定间隔时间
  */
 public TimerTaskEvent(int intervalTime) {
  this(0, false, 0, -1, intervalTime);
 }

 public long getStartTime {
  return startTime;
 }

 public void setStartTime(long startTime) {
  this.startTime = startTime;
 }

 public boolean isStartAction {
  return startAction;
 }

 public void setStartAction(boolean startAction) {
  this.startAction = startAction;
 }

 public long getEndTime {
  return endTime;
 }

 public void setEndTime(long endTime) {
  this.endTime = endTime;
 }

 public int getActionCount {
  return actionCount;
 }

 public void setActionCount(int actionCount) {
  this.actionCount = actionCount;
 }

 public int getIntervalTime {
  return intervalTime;
 }

 public void setIntervalTime(int intervalTime) {
  this.intervalTime = intervalTime;
 }

}

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

package net.sz.engine.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.sz.engine.structs.ObjectGlobal;
import net.sz.engine.utils.MailUtil;
import net.sz.engine.utils.StringUtil;
import org.apache.log4j.Logger;
import org.jboss.jandex.Main;

/**
 * 线程模型
 * <br>
 * author 失足程序员<br>
 * mail 492794628@qq.com<br>
 * phone 13882122019<br>
 */
public class ThreadModel implements Runnable {

 private static final Logger log = Logger.getLogger(ThreadModel.class);
 private static long threadID = 0;
 protected static final Object SYN_OBJECT = new Object;
 protected long tid;
 protected String name;
 protected long lastSendMail = 0;

 protected final ArrayList<MyThread> threads = new ArrayList<>;
 /**
  * 任务列表 线程安全的任务列表
  */
 //protected final List<TaskModel> taskQueue = new ArrayList<>;
 protected final ConcurrentLinkedQueue<TaskEvent> taskQueue = new ConcurrentLinkedQueue<>;

 /**
  *
  */
 protected final List<TimerTaskEvent> timerQueue = new ArrayList<>;

 // false标识删除线程
 protected volatile boolean runing = true;

 public ThreadModel(ThreadGroup group) {
  this(group, "无名", 1);
 }

 public ThreadModel(String name) {
  this(ThreadPool.UnknownThreadGroup, name, 1);
 }

 public ThreadModel(ThreadGroup group, String name, int threadCount) {
  this(group, name, threadCount, null);
 }

 public ThreadModel(ThreadGroup group, String name, int threadCount, Runnable runnable) {
  synchronized (SYN_OBJECT) {
threadID++;
tid = threadID;
  }
  for (int i = 1; i <= threadCount; i++) {
 MyThread thread;
if (runnable == null) {
thread = new MyThread(tid, group, this, name + "-" + tid + "-" + i);
} else {
thread = new MyThread(tid, group, runnable, name + "-" + tid + "-" + i);
 }
 thread.start;
 threads.add(thread);
  }
  this.name = name;
 }

 /**
  * 线程名字
  *
  * @return
  */
 public String getName {
  return name;
 }

 /**
  * 获取线程的自定义id
  *
  * @return
  */
 public long getId {
  return this.tid;
 }

 /**
  * 增加新的任务 每增加一个新任务,都要唤醒任务队列
  *
  * @param runnable
  */
 public void addTask(TaskEvent runnable) {
  taskQueue.add(runnable);

  synchronized (taskQueue) {
/* 唤醒队列, 开始执行 */
 taskQueue.notifyAll;
  }
 }

 /**
  * 向线程添加定时器任务
  *
  * @param runnable
  */
 public void addTimer(TimerTaskEvent runnable) {
  synchronized (timerQueue) {
if (runing) {
//一开始执行一次
if (runnable.startAction) {
 addTask(runnable);
 }
 timerQueue.add(runnable);
} else {
log.error("线程已经停止");
 }
  }
 }

 // <editor-fold defaultstate="collapsed" desc="定时器线程执行器 public void timerRun">
 /**
  * 定时器线程执行器
  */
 public void timerRun {
  ArrayList<TimerTaskEvent> taskModels;
  synchronized (timerQueue) {
// 队列不为空的情况下 取出队列定时器任务
taskModels = new ArrayList<>(timerQueue);
  }
  if (!taskModels.isEmpty) {
for (TimerTaskEvent timerEvent : taskModels) {
int execCount = timerEvent.getRunOther.getintValue("Execcount");
long lastTime = timerEvent.getRunOther.getlongValue("LastExecTime");
long nowTime = System.currentTimeMillis;
if (lastTime == 0) {
timerEvent.getRunOther.put("LastExecTime", nowTime);
} else if (timerEvent.isCancel) {
//如果任务已经取消
synchronized (timerQueue) {
 timerQueue.remove(timerEvent);
 }
log.debug("清理定时器任务:" + timerEvent.getClass.getName);
} else if (nowTime > timerEvent.getStartTime // 是否满足开始时间
&& (nowTime - timerEvent.getSubmitTime > timerEvent
.getIntervalTime)// 提交以后是否满足了间隔时间
&& (timerEvent.getEndTime <= 0 || nowTime < timerEvent
.getEndTime) // 判断结束时间
&& (nowTime - lastTime >= timerEvent
.getIntervalTime)) // 判断上次执行到目前是否满足间隔时间
 {
// 提交执行定时器最先执行
this.addTask(timerEvent);
// 记录
execCount++;
timerEvent.getRunOther.put("Execcount", execCount);
timerEvent.getRunOther.put("LastExecTime", nowTime);
nowTime = System.currentTimeMillis;
// 判断删除条件
if ((timerEvent.getEndTime > 0 && nowTime < timerEvent.getEndTime)
|| (timerEvent.getActionCount > 0 && timerEvent.getActionCount <= execCount)) {
synchronized (timerQueue) {
 timerQueue.remove(timerEvent);
 }
log.debug("清理定时器任务:" + timerEvent.getClass.getName);
 }
 }
 }
  }
 }
 // </editor-fold>

 // <editor-fold defaultstate="collapsed" desc="查看线程堆栈 public void showStackTrace">
 /**
  *
  * 查看线程堆栈
  */
 public void showStackTrace {
  StringBuilder buf = new StringBuilder;
  for (MyThread currentThread : threads) {
long procc = System.currentTimeMillis - currentThread.getLastExecuteTime;
if (procc > 5 * 1000 && procc < 864000000L) {//小于10天//因为多线程操作时间可能不准确
buf.append("线程[")
 .append(currentThread.getName)
.append("]可能已卡死 -> ")
.append(procc / 1000f)
.append("s\n ")
.append("执行任务:")
 .append(currentThread.getLastCommand.getClass.getName);
try {
StackTraceElement elements = currentThread.getStackTrace;
for (int i = 0; i < elements.length; i++) {
buf.append("\n ")
 .append(elements[i].getClassName)
.append(".")
 .append(elements[i].getMethodName)
.append("(").append(elements[i].getFileName)
.append(";")
.append(elements[i].getLineNumber).append(")");
 }
} catch (Exception e) {
 buf.append(e);
 }
buf.append("\n++++++++++++++++++++++++++++++++++");
 }
  }
  String toString = buf.toString;
  if (!StringUtil.isNullOrEmpty(toString)) {
 log.error(toString);
if (System.currentTimeMillis - lastSendMail > 5 * 60 * 1000) {
lastSendMail = System.currentTimeMillis;
MailUtil.sendMail("线程执行已卡死 -> 游戏id-" + ObjectGlobal.GameID + " 平台-" + ObjectGlobal.Platform + " 服务器id-" + ObjectGlobal.ServerID, toString);
 }
  }
 }
 // </editor-fold>

 @Override
 public void run {
  MyThread currentThread = (MyThread) Thread.currentThread;
  while (runing) {
while (taskQueue.isEmpty && runing) {
try {
/* 任务队列为空,则等待有新任务加入从而被唤醒 */
synchronized (taskQueue) {
taskQueue.wait(500);
 }
} catch (InterruptedException ie) {
 log.error(ie);
 }
 }
/* 取出任务执行 */
if (runing) {
currentThread.lastCommand = null;
currentThread.lastCommand = taskQueue.poll;
 }
if (currentThread.lastCommand != null) {
if (currentThread.lastCommand.isCancel) {
//如果任务已经取消
continue;
 }
/* 执行任务 */
// r.setSubmitTimeL;
currentThread.lastExecuteTime = System.currentTimeMillis;
try {
 currentThread.lastCommand.run;
} catch (Exception e) {
log.error("工人<“" + currentThread.getName + "”> 执行任务<" + currentThread.lastCommand.getClass.getName + "> 遇到错误: ", e);
 }
long timeL1 = System.currentTimeMillis - currentThread.lastExecuteTime;
if (timeL1 <= 20) {

} else if (timeL1 <= 100L) {
log.info("工人<“" + currentThread.getName + "”> 完成了任务:" + currentThread.lastCommand.toString + " 执行耗时:" + timeL1);
} else if (timeL1 <= 200L) {
log.info("工人<“" + currentThread.getName + "”> 长时间执行 完成任务:" + currentThread.lastCommand.toString + " “考虑”任务脚本逻辑 耗时:" + timeL1);
} else {
log.info("工人<“" + currentThread.getName + "”> 超长时间执行完成 任务:" + currentThread.lastCommand.toString + " “考虑是否应该删除”任务脚本 耗时:" + timeL1);
 }
currentThread.lastExecuteTime = 0;
 }
  }
  log.error("线程结束, 工人<“" + Thread.currentThread.getName + "”>退出");
 }

 /**
  * 自定义线程
  */
 public class MyThread extends Thread {

  /**
   *
   * @param tid 自定义线程id
   * @param group 分组
   * @param run 执行方法
   * @param name 线程名称
*/
  public MyThread(long tid, ThreadGroup group, Runnable run, String name) {
super(group, run, name);
this._id = tid;
  }

  //线程的自定义id
  public long _id;
  //正在执行的任务
  public volatile TaskEvent lastCommand;
  //开始执行任务的时间
  public volatile long lastExecuteTime = 0;

  public TaskEvent getLastCommand {
return lastCommand;
  }

  public long getLastExecuteTime {
return lastExecuteTime;
  }

  /**
   * 返回线程自定义id
   *
   * @return
*/
  @Override
  public long getId {
return _id;
  }

 }

 /**
  * 停止线程,设置线程的停止状态,并不会马上终止线程
  */
 public void stop {
  this.runing = false;
 }

 public boolean isRuning {
  return runing;
 }

 @Override
 public String toString {
  return "Thread{" + "tid=" + tid + ",Name=" + this.getName + '}';
 }

}

我从 ThreadModel 构造函数的

 public ThreadModel(ThreadGroup group, String name, int threadCount, Runnable runnable) {
  synchronized (SYN_OBJECT) {
threadID++;
tid = threadID;
  }
  for (int i = 1; i <= threadCount; i++) {
 MyThread thread;
if (runnable == null) {
thread = new MyThread(tid, group, this, name + "-" + tid + "-" + i);
} else {
thread = new MyThread(tid, group, runnable, name + "-" + tid + "-" + i);
 }
 thread.start;
 threads.add(thread);
  }
  this.name = name;
 }

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

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

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

字很丑,请见谅

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

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

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

package net.sz.engine.thread;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * <br>
 * author 失足程序员<br>
 * mail 492794628@qq.com<br>
 * phone 13882122019<br>
 */
class TimerThread extends Thread {

 private static final Object SYN_OBJECT = new Object;

 public TimerThread {
  super(ThreadPool.GloblThreadGroup, "Global Timer Thread");
 }

 @Override
 public void run {
  while (true) {
synchronized (SYN_OBJECT) {
try {
SYN_OBJECT.wait(2);
} catch (InterruptedException ex) {
 }
 }
HashMap<Long, ThreadModel> hashMap = new HashMap<>(ThreadPool.getThreadMap);
for (Map.Entry<Long, ThreadModel> entrySet : hashMap.entrySet) {
Long key = entrySet.getKey;
ThreadModel value = entrySet.getValue;
 value.timerRun;
 }
  }
 }

}

线程模型的管理器

package net.sz.engine.thread;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import net.sz.engine.script.manager.ScriptManager;
import net.sz.engine.timer.GlobTimerEvent;
import net.sz.engine.timer.PrintlnServerMemoryTimerEvent;
import org.apache.log4j.Logger;

/**
 * 线程管理器
 *
 * <br>
 * author 失足程序员<br>
 * mail 492794628@qq.com<br>
 * phone 13882122019<br>
 */
public class ThreadPool {

 static private final Logger log = Logger.getLogger(ThreadPool.class);
 static public final long GloblThread;
 static private final TimerThread GloblTimerThread;
 static final long CheckThreadTimerThreadModel;
 static public final ThreadGroup GloblThreadGroup = new ThreadGroup("Global ThreadGroup");
 static public final ThreadGroup UnknownThreadGroup = new ThreadGroup(GloblThreadGroup, "Unknown ThreadGroup");
 static private final ConcurrentHashMap<Long, ThreadModel> threadMap = new ConcurrentHashMap<>;

 public static void main(String[] args) {

  ThreadPool.addTimerTask(GloblThread, new TimerTaskEvent(1000) {

 @Override
public void run {

log.error("ssssss");
 }
  });
 }

 static {
  //创建全局线程
  GloblThread = addThreadModel(GloblThreadGroup, "GloblThread");
  //执行指定任务定时触发脚步
  addTimerTask(GloblThread, new GlobTimerEvent(ScriptManager.getInstance.getBaseScriptEntry));
  //查询服务器消耗定时模型
  addTimerTask(GloblThread, new PrintlnServerMemoryTimerEvent);
  //创建定时器线程
  GloblTimerThread = new TimerThread;
  GloblTimerThread.start;
  //检查线程卡死情况
  CheckThreadTimerThreadModel = addThreadModel(GloblThreadGroup, "Check Thread Timer Event");
  addTimerTask(CheckThreadTimerThreadModel, new CheckThreadTimerEvent);
 }

 /**
  * 删除指定id线程模型的时候回设置状态为停止状态
  *
  * @param tid
  * @return
  */
 static public ThreadModel remove(long tid) {
  ThreadModel remove = threadMap.remove(tid);
  if (remove != null) {
 remove.stop;
  }
  return remove;
 }

 /**
  * 获取线程池中所有线程
  *
  * @return
  */
 static public ConcurrentHashMap<Long, ThreadModel> getThreadMap {
  return threadMap;
 }

 /**
  * 获取线程池的一个线程
  *
  * @param threadId
  * @return
  */
 static public ThreadModel getThreadModel(long threadId) {
  ThreadModel get = threadMap.get(threadId);
  if (get == null) {
log.error("无法找到线程模型:" + threadId, new Exception("无法找到线程模型:" + threadId));
  }
  return get;
 }

 /**
  * 向线程池注册一个线程
  * <br>
  * 默认分组 UnknownThreadGroup
  *
  * @param name 线程名称
  * @return
  */
 static public long addThreadModel(String name) {
  return addThreadModel(UnknownThreadGroup, name);
 }

 /**
  * 向线程池注册一个线程
  * <br>
  * 默认分组 UnknownThreadGroup
  *
  * @param name 线程名称
  * @param threadcount 线程量
  * @return
  */
 static public long addThreadModel(String name, int threadcount) {
  return addThreadModel(UnknownThreadGroup, name, threadcount);
 }

 /**
  * 向线程池注册一个线程
  *
  * @param group 线程分组信息
  * @param name 线程名称
  * @return
  */
 static public long addThreadModel(ThreadGroup group, String name) {
  return addThreadModel(group, name, 1);
 }

 /**
  * 向线程池注册一个线程
  *
  * @param group 线程分组信息
  * @param name 线程名称
  * @param threadcount 线程量
  * @return
  */
 static public long addThreadModel(ThreadGroup group, String name, int threadcount) {
  return addThreadModel(group, name, null, threadcount);
 }

 /**
  * 向线程池注册一个线程
  *
  * @param group 线程分组信息
  * @param name 线程名称
  * @param runnable
  * @param threadcount 线程量
  * @return
  */
 static public long addThreadModel(ThreadGroup group, String name, Runnable runnable, int threadcount) {
  ThreadModel threadModel = new ThreadModel(group, name, threadcount, runnable);
  return addThreadModel(threadModel);
 }

 /**
  * 向线程池注册一个线程
  *
  * @param threadModel
  */
 static public long addThreadModel(ThreadModel threadModel) {
  threadMap.put(threadModel.getId, threadModel);
  return threadModel.getId;
 }

 /**
  * 添加任务
  *
  * @param threadId
  * @param task
  * @return
  */
 static public boolean addTask(long threadId, TaskEvent task) {
  ThreadModel threadModel = getThreadModel(threadId);
  if (threadModel != null) {
 threadModel.addTask(task);
return true;
  }
  return false;
 }

 /**
  * 添加定时器任务
  *
  * @param threadId
  * @param task
  * @return
  */
 static public boolean addTimerTask(long threadId, TimerTaskEvent task) {
  ThreadModel threadModel = getThreadModel(threadId);
  if (threadModel != null) {
 threadModel.addTimer(task);
return true;
  }
  return false;
 }

 /**
  * 添加任务,添加任务到当前线程
  *
  * @param task
  * @return
  */
 static public boolean addCurrentThreadTask(TaskEvent task) {
  Thread currentThread = Thread.currentThread;
  if (currentThread instanceof ThreadModel.MyThread) {
long threadId = currentThread.getId;
ThreadModel threadModel = getThreadModel(threadId);
if (threadModel != null) {
 threadModel.addTask(task);
return true;
 }
  }
  return false;
 }

 /**
  * 添加定时器任务,添加任务到当前线程
  *
  * @param task
  * @return
  */
 static public boolean addCurrentThreadTimerTask(TimerTaskEvent task) {
  Thread currentThread = Thread.currentThread;
  if (currentThread instanceof ThreadModel.MyThread) {
long threadId = currentThread.getId;
ThreadModel threadModel = getThreadModel(threadId);
if (threadModel != null) {
 threadModel.addTimer(task);
return true;
 }
  }
  return false;
 }
}

接下来我们看看使用情况

上篇文章中线程介绍代码

public static void main(String[] args) throws InterruptedException {
  //线程并行情况,有多个线程执行多个任务/函数
  new Thread(new Run1).start;
  new Thread(new Run2).start;
 }

 //任务1
 static class Run1 implements Runnable {

  @Override
  public void run {
//执行任务1
 run1;
//执行任务3
 run3;
  }
 }
 //任务2

 static class Run2 implements Runnable {

  @Override
  public void run {
//执行任务3
 run3;
//执行任务1
 run1;
//执行任务2
 run2;
  }
 }

 //任务1
 public static void run1 {
  System.out.println("run1->" + System.currentTimeMillis);
 }

 //任务2
 public static void run2 {
  System.out.println("run2->" + System.currentTimeMillis);
 }

 //任务3
 public static void run3 {
  System.out.println("run3->" + System.currentTimeMillis);
 }

我把代码切换模式

 public static void main(String[] args) throws InterruptedException {
  //线程并行情况,有多个线程执行多个任务/函数
  long test1 = ThreadPool.addThreadModel("测试线程-1");
  long test2 = ThreadPool.addThreadModel("测试线程-2");
  //添加任务
  ThreadPool.addTask(test1, new Run1);
  ThreadPool.addTask(test2, new Run2);
  //添加定时器任务
  ThreadPool.addTimerTask(test1, new TimerRun1);
  ThreadPool.addTimerTask(test2, new TimerRun2);
 }
 //任务1
 static class Run1 extends TaskEvent {
  @Override
  public void run {
//执行任务1
 run1;
//执行任务3
 run3;
  }
 }
 //任务1
 static class TimerRun1 extends TimerTaskEvent {
  public TimerRun1 {
super(500);//500毫秒无限制执行
  }
  @Override
  public void run {
//执行任务1
 run1;
//执行任务3
 run3;
  }
 }
 //任务2
 static class Run2 extends TaskEvent {
  @Override
  public void run {
//执行任务3
 run3;
//执行任务1
 run1;
//执行任务2
 run2;
  }
 }
 //任务2
 static class TimerRun2 extends TimerTaskEvent {
  public TimerRun2 {
super(500);//500毫秒无限制执行
  }
  @Override
  public void run {
//执行任务3
 run3;
//执行任务1
 run1;
//执行任务2
 run2;
  }
 }
 //任务1
 public static void run1 {
  System.out.println("run1->" + System.currentTimeMillis);
 }
 //任务2
 public static void run2 {
  System.out.println("run2->" + System.currentTimeMillis);
 }
 //任务3
 public static void run3 {
  System.out.println("run3->" + System.currentTimeMillis);
 }

接下来我们看看执行效果

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

一切正常;

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

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

那么优缺点在哪里呢?

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

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

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

(0)

相关推荐

  • 浅析Java内存模型与垃圾回收

    1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法,这个计数器记录正在执行的虚拟机字节码指令的地址,如果执行的是Native方法,这个计算器值为空. Java虚拟机栈:线程私有的,其生命周期和线程一致,每个方法执行时都会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口等信息. 本地方法栈:与虚拟机栈功能类似,只不过虚拟机栈为虚拟机执行J

  • 浅谈Java利用表格模型创建表格 原创

    用来创建表格的 JTable 类并不负责存储表格中的数据,而是由表格模型负责存储.当利用 JTable 类直接创建表格时,只是将数据封装到了默认的表格模型中.接下来,我们来学习表格模型的使用方法. 利用表格模型创建表格 接口 TableModel 定义了一个表格模型,抽象类 AbstractTableModel 实现了 TableModel 接口的大部分方法,只有一下三个抽象方法没有实现. (1)public int getRowCount() (2)public int getColumnCo

  • Java 高并发七:并发设计模型详解

    1. 什么是设计模式 在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题 ,所提出的解决方案.这个术语是由埃里希·伽玛(Erich Gamma)等人在1990年代从建筑设计领 域引入到计算机科学的. 著名的4人帮: Erich Gamma,Richard Helm, Ralph Johnson ,John Vlissides (Gof) <设计模式:可复用面向对象软件的基础>收录23种模式 2. 单例模式 单例对象的类必须保证只有一个实例存在.许

  • Java3D实例之创建空间几何模型的实现方法

    Java3D,算是比较古老的技术,Java8中Oracle对JavaFX支持了Java3D. 相关资料参照Oracle官网 <JDK8目前还没有正式发布 Early Access版本下载地址 http://jdk8.java.net>环境搭建Java3D开发环境,JDK下载见Oracle官网.安装后在安装目录下的lib文件中找到Java3D驱动包,添加的自己的项目中Java3D实现简单几何空间图形说明: 实例应用:创建3D直线 复制代码 代码如下: package com.java3d.den

  • Java并发编程中的生产者与消费者模型简述

    概述 对于多线程程序来说,生产者和消费者模型是非常经典的模型.更加准确的说,应该叫"生产者-消费者-仓库模型".离开了仓库,生产者.消费者就缺少了共用的存储空间,也就不存在并非协作的问题了. 示例 定义一个场景.一个仓库只允许存放10件商品,生产者每次可以向其中放入一个商品,消费者可以每次从其中取出一个商品.同时,需要注意以下4点: 1.  同一时间内只能有一个生产者生产,生产方法需要加锁synchronized. 2.  同一时间内只能有一个消费者消费,消费方法需要加锁synchro

  • Java 23种设计模型详解

    设计模式(Design Patterns)                                   --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样.项目中合理的运用设计模式可以完美的解决很多问题,每

  • Java 高并发三:Java内存模型和线程安全详解

    网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存.数据在主存中会有一份,在工作内存中也有一份.工作内存和主存之间会有各种原子操作去进行同步. 下图来源于这篇Blog 但是由于Java版本的不断演变,内存模型也进行了改变.本文只讲述Java内存模型的一些特性,无论是新的内存模型还是旧的内存模型,在明白了这些特性以后,看起来也会更加清晰. 1. 原子性 原子性是指一个操作是不可中断的.即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰

  • java自定义线程模型处理方法分享

    看过我之前文章的园友可能知道我是做游戏开发,我的很多思路和出发点是按照游戏思路来处理的,所以和web的话可能会有冲突,不相符合. 来说说为啥我要自定义线程模型呢? 按照我做的mmorpg或者mmoarpg游戏划分,线程被划分为,主线程,全局同步线程,聊天线程,组队线程,地图线程,以及地图消息分发派送线程等: 一些列,都需要根据我的划分,以及数据流向做控制. 游戏服务器,主要要做的事情,肯定是接受玩家的 命令请求 -> 相应的操作 -> 返回结果: 在服务器端所有的消息都会注册到消息管理器里,然

  • JAVA 自定义线程池的最大线程数设置方法

    一:CPU密集型: 定义:CPU密集型也是指计算密集型,大部分时间用来做计算逻辑判断等CPU动作的程序称为CPU密集型任务.该类型的任务需要进行大量的计算,主要消耗CPU资源.  这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数. 特点:    01:CPU 使用率较高(也就是经常计算一些复杂的运算,逻辑处理等情况)非常多的情况下使用    02:针对单台机

  • 三种Java自定义DNS解析器方法与实践

    目录 1.InMemoryDnsResolver 2.SystemDefaultDnsResolver 3.自定义DnsResolver 4.连接池管理器 5.测试 前言: 最近终于用上了高性能的测试机(54C96G * 3),相较之前的单机性能提升了三倍,数量提升了三倍,更关键的宽带提单机升了30倍不止,总体讲提升了100多倍,这下再也不用担心单机压力机瓶颈,直接原地起飞. 不过没高兴5分钟,我发现接口居然请求不通,经过一阵拨乱反正终于找到原因:域名无法解析,IP无法直接访问. 自然而然,解决

  • Python自定义线程池实现方法分析

    本文实例讲述了Python自定义线程池实现方法.分享给大家供大家参考,具体如下: 关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主要思路: 任务获取和执行: 1.任务加入队列,等待线程来获取并执行. 2.按需生成线程,每个线程循环取任务. 线程销毁: 1.获取任务是终止符时,线程停止. 2.线程池close()时,向任务队列加入和已生成线程等量的

  • Java自定义线程池的实现示例

    目录 一.Java语言本身也是多线程,回顾Java创建线程方式如下: 二.JDK线程池工具类. 三.业界知名自定义线程池扩展使用. 一.Java语言本身也是多线程,回顾Java创建线程方式如下: 1.继承Thread类,(Thread类实现Runnable接口),来个类图加深印象. 2.实现Runnable接口实现无返回值.实现run()方法,啥时候run,黑话了. 3.实现Callable接口重写call()+FutureTask获取. public class CustomThread {

  • Java中线程的基本方法使用技巧

    java中线程的基本方法的熟练使用是精通多线程编程的必经之路,线程相关的基本方法有wait,notify,notifyAll,sleep,join,yield等,本文浅要的介绍一下它们的使用方式. 线程的状态图 java将操作系统中的就绪和运行两种状态统称为可运行状态,java中线程的状态可以认为有以上六种. wait 调用该方法的线程进入WAITING状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait()方法后,会释放对象的锁. 因此,wait方法一般用在同步方法或同步代码

  • 简单了解Java创建线程两种方法

    这篇文章主要介绍了简单了解Java创建线程两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Java实现并启动线程有两种方法 1.写一个类继承自Thread类,重写run方法.用start方法启动线程 2.写一个类实现Runnable接口,实现run方法.用new Thread(Runnable target).start()方法来启动 注意:start方法不是立即执行多线程,而是使得该线程变为就绪态(Runnable) 1.通过扩展Th

  • Java查看线程运行状态的方法详解

    目录 一.查看线程的运行状态 二.解题思路 三.代码详解 一.查看线程的运行状态 题目 线程有以下6种状态:新建.运行.阻塞.等待.计时等待和终止. new新线程时,线程处于新建 状态. 调用start()方法时,线程处于运行状态. 当线程需要获得对象的内置锁,而该锁正被其他线程拥有,线程处于阻塞状态. 线程等待其他线程通知调度表可以运行时,该线程处于等待状态. 对于一些含有时间参数的方法,如 Thread 类的 sleep()方法,可以使线程处于计时等待状态. 当run()方法运行完毕或出现异

  • Java 自定义线程池和线程总数控制操作

    1 概述 池化是常见的思想,线程池是非常典型的池化的实现,<Java并发编程实战>也大篇幅去讲解了Java中的线程池.本文实现一个简单的线程池. 2 核心类 [1]接口定义 public interface IThreadPool<Job extends Runnable> { /** * 关闭线程池 */ public void shutAlldown(); /** * 执行任务 * * @param job 任务 */ public void execute(Job job);

  • Android开发笔记之:如何安全中止一个自定义线程Thread的方法

    经研究,我推荐这种写法: 复制代码 代码如下: <SPAN xmlns="http://www.w3.org/1999/xhtml">/*自定义线程*/ class MyThread implements Runnable{  public void run() {   // TODO Auto-generated method stub //  定义自己的变量                         while(!Thread.currentThread().is

随机推荐