Aquellos que han leído mis artículos anteriores pueden saber que estoy haciendo desarrollo de juegos. Muchas de mis ideas y puntos de partida se manejan de acuerdo con las ideas del juego, por lo que puede haber conflictos con la web y no está en línea con ella.
Déjame decirte por qué quiero personalizar el modelo de subprocesos.
De acuerdo con el juego MMORPG o MMORPG que hice, los hilos se dividen en el hilo principal, el hilo de sincronización global, el hilo de chat, el hilo del equipo, el hilo del mapa y la distribución de mensajes de mapa y el hilo de entrega, etc.
Algunas columnas deben controlarse de acuerdo con mi división y flujo de datos.
Lo principal que debe hacer en el servidor de juegos es aceptar la solicitud de comando del jugador -> Operación correspondiente -> devolver el resultado;
Todos los mensajes en el lado del servidor se registrarán en el administrador de mensajes, y luego el modelo de subproceso se especificará cuando el mensaje esté registrado.
Si el mensaje debe enviarse al hilo del mapa del reproductor para su procesamiento, al registrar el mensaje, debe usar el modelo de subproceso (mapa de distribución de mensajes y hilo de envío);
Analicemos primero el modelo de hilo;
Antes de mirar el código del modelo de hilo, primero miro mi modelo de tarea
paquete net.sz.engine.thread; import java.io.Serializable; import org.apache.log4j.logger; import.sz.engine.structs.objectattribute; import.sz.engine.structs.objectGlobal;/** * modelo de tarea * * <BR> * autor cayendo <br> * mail 492794628 13882122019 <br> */clase pública de la clase Taskevent implementa serializable, clonable {private static final logger log = logger.getLogger (taskevent.class); Private static final Long SerialVersionUid = 4196020659994845804l; // Datos de ejecución de tiempo de ejecución Transitorio privado final ObjectAttribute Runother = new ObjectAttribute; // Tiempo de creación de tareas protegido Long Createtime; // Tarea ID única protegida Long TaskId; // Tarea cancelada protegida boolean cancelar = falso; public Taskevent {this.runother.put ("SubsitteMe", System.CurrentTimemillis); createTime = System.CurrentTimemillis; cancelar = falso; taskId = objectGlobal.getUUid; } public Long Long GetCreateTime {return CreateTime; } public void setCreateTime (Long CreateTime) {this.CreateTime = CreateTime; } public Long GetSubmitTime {return this.runother.getLongValue ("SubsitteMe"); } public ObjectAttribute getRunother {return runother; } public boolean IsCancel {return Cancel; } public void setCancel (boolean cancel) {this.cancel = cancelar; } ejecución pública abstracta vacía; @Override Public Object Clone lanza clonenotsupportedException {return super.clone; // Para cambiar el cuerpo de los métodos generados, elija Herramientas | Plantillas. }}paquete net.sz.engine.thread;/** * Ejecutor de temporizador * * <br> * Autor Falló programador <br> * correo [email protected] <br> * teléfono 13882122019 <br> */public abstract class TimeRtaSKevent se extiende taskevent {privado final de serialversionUdveruid = -8333129629526446920764920764920769207692074992076920769207499207TVIRS. / *** Tiempo para comenzar la ejecución*/ Proteged Long Starttime; / *** si ejecutar una vez al principio*/ protegido boolean Startaction; / *** Tiempo de finalización*/ Protegido de tiempo de extremos largo; / *** Número de ejecuciones*/ Protected int actionCount; / *** Tiempo de ejecución del intervalo*/ protegido int intervaltime; / ***** @param starttime especifique la hora de inicio* @param se adtacta si se ejecuta una vez al principio* @param endtime especificar la hora de final this.starttime = starttime; this.StartAction = isStartAction; this.endtime = endtime; this.ActionCount = ActionCount; this.intervaltime = intervaltime; } / *** Especifique la hora de ejecución de inicio de la tarea** @param Starttime Especifique la hora de inicio* @param isStartaction si se ejecuta una vez al inicio* @param ActionCount especifica el número de ejecuciones* @param intervaltime tiempo especifica la hora de intervalo* / public timertaskent (tiempo de inicio largo, boolean isStartaction, intactionCount, int intervalo de intervalo (esto (este (startation, ISStArtation, ISStArtAction, ISStArtAction, ISStArtAction, ISStArtAction, ISStArtAction, ISStArtAction, ISStArtAction, ISSTArtAction, ISSTAR ActionCount, Intervaltime); } / *** El tiempo de finalización especificado es el tiempo de finalización, y el número de ejecuciones no es necesariamente suficiente** @param es una medida de ejecución si se ejecuta una vez al principio* @param Endtime especifica el tiempo final* @param ActionCount especifica el número de ejecuciones* @Param Intervaltime especificar el tiempo de intervalo** / public Timertaskevent (BoLean es estacionado, el tiempo de fin de largo, INTATATTION, INTERVALTIME, INTERTIME {INTERTIME, INTERTIME, INTERTIME { este (0, ISStartaction, Endtime, ActionCount, Intervaltime); } / *** Especifique la hora de inicio y la hora de finalización** @param Starttime Especifique la hora de inicio* @param Endtime Especifique la hora de finalización* @param intervaltime Especifique el tiempo de intervalo* / public timerTasKentvent (tiempo de inicio largo, tiempo largo, int intervaltime) {this (tiempo de inicio, falso, tiempo de finalización, -1, intervaltime); } / *** Tiempos de ejecución especificados y tiempo de intervalo** @param ActionCount Especifique el número de ejecuciones* @param Intervaltime Especifique el tiempo de intervalo* / public TimeTasKevent (int ActionCount, int intervaltime) {this (0, false, 0, ActionCount, Intervaltime); } / *** Ejecución ilimitada después del envío* @param intervaltime tiempo de intervalo especificado* / public timeTASKEVEVE (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 Long Getendtime {return Endtime; } public void setendtime (largo 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; }}
Aquí están el modelo de tarea y el modelo de tarea del temporizador;
paquete net.sz.engine.thread; import java.util.arrayList; import java.util.list; import java.util.concurrent.concurrentLinkedqueue; import net.sz.engine.structs.objectGlobal; import.sz.engine.utils.mailutil; import.sz.engine.util.util.sutil. org.apache.log4j.logger; import org.jboss.jandex.main;/** * Modelo de hilo * <br> * Programador fallido de autor <br> * correo [email protected] <br> * teléfono 13882122019 <br> */clase pública TreveModel implementados renovables {logger estatic logger estatic final = privado Logger.getLogger (ThreadModel.Class); PRIVADO ESTÁTICO LARGO TRADIDO = 0; Objeto final estático protegido syn_object = nuevo objeto; protegido largo tid; nombre de cadena protegido; Protegido largo LastsendMail = 0; ArrayList final protegido <MyThread> Threads = New ArrayList <>; /*** Lista de tareas de la lista de tareas Safe*/// Lista final protegida <KaskModel> taskqueue = new ArrayList <>; Final concurrente Final Protegido <TasKEvent> taskQueue = new concurrentLinkedQueue <>; / ***/ Lista final protegida <TimeRtaSKevent> Timerqueue = new ArrayList <>; // Falso Identidad Eliminar el hilo protegido Boolean volátil Running = True; public ThreadModel (grupo ThreadGroup) {this (grupo, "sin nombre", 1); } public threadmodel (nombre de cadena) {this (threadpool.unknownThreadGroup, nombre, 1); } public threadmodel (grupo de grupo ThreadGrup, nombre de cadena, int ThreadCount) {this (grupo, nombre, threadcount, null); } public ThreadModel (grupo de grupo de ThreadGroup, nombre de cadena, int ThreadCount, runnable runnable) {SynChronized (syn_object) {threadid ++; tad = 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, grupo, runnable, nombre + "-" + tid + "-" + i); } thread.start; hilts.add (hilo); } this.name = name; } / ** * nombre del hilo * * @return * / public string getName {return name; } / ** * Obtenga la identificación personalizada del hilo * * @return * / public Long getid {return this.tid; } / ** * Agregue una nueva tarea para cada nueva tarea, la cola de tareas debe despertarse * * @param runnable * / public void addTask (Taskevent runnable) {taskqueue.add (runnable); Sincronizado (TaskQueue) {/ * despertar la cola y comenzar a ejecutar */ taskqueue.notifyall; }}/** * Agregue una tarea de temporizador al hilo * * @param runnable */public void addTimer (TimeRTASKEVEVE Runnable) {SynChronized (TimerQueue) {if (runing) {// ejecutar una vez al principio if (runnable.startaction) {addTask (runnable); } timerqueue.add (runnable);} else {log.error ("el hilo ha detenido"); }}}} // <editor-fold DefaultState = "collapsed" desc = "Ejecutor de subproceso de temporizador public void timerrun"> / *** Timer Thread Executor* / public void timerrun {ArrayList <TimeRtaSKevent> TaskModels; Synchronized (TimerQueue) {// Si la cola no está vacía, saque el TaskModels de Tareas del Temporizador de cola = new ArrayList <> (Timerqueue); } if (! TaskModels.IsEmpty) {for (TimeRTASKEVEVE TimeReVent: TaskModels) {int ExecCount = timerEvent.getRunother.getTinValue ("ExecCount"); Long LastTime = timerEvent.getRunother.getLongValue ("lastExectime"); Long ahora = System.CurrentTimemillis; if (LastTime == 0) {timerEvent.getRunother.put ("LastExectime", ahora Time);} else if (timerEvent.iscancel) {// Si la tarea se ha cancelado sincronizado (TimerQueue) {Timerqueue.remove (TimerEvererEvent); } log.debug ("Limpie la tarea del temporizador:" + timerEvent.getClass.getName);} else if (ahora> timerEvent.getStarttime // si la hora de inicio está satisfecha && (ahora TimeReVentEvent.getSubMitTime> timerEvent.getIntervalTime) // la hora del intervalo está satisfecho después de la envío && (timerEvent. timerEvent.getendtime) // Determine el tiempo de finalización && (nowtime - lasttime> = timerEvent.getIntervaltime)) // Determine si el tiempo de intervalo ha sido satisfecho desde la última ejecución {// El temporizador de ejecución de sumisión es el primero para ejecutar this.addtask (timerEvent); // registro ++; timerEsver.getRunother.put ("ejecutCount", execCount);timerEvent.getRunOther.put("LastExecTime", nowTime);nowTime = System.currentTimeMillis;// Determine the deletion condition if ((timerEvent.getEndTime > 0 && nowTime < timerEvent.getEndTime)|| (timerEvent.getActionCount > 0 && timerEvent.getActionCount <= execCount)) {synchronized (timerQueue) { Timerqueue.remove (TimeReVent); } log.debug ("Tarea del temporizador de limpieza:" + timerEvent.getClass.getName); }}}}}}} // </editor-fold> // <editor-fold defaultState = "collapsed" desc = "ver pila de hilo public void showStacktrace">/**** ver pila de hilo*/public void showStackTrace {stringBuilder buf = new StringBuilder; for (MyThread CurrentThread: Threads) {Long Procc = System.CurrentTimemillis - CurrentThread.getLastExecutTime; if (Procc> 5 * 1000 && Procc <86400000l) {// Less de 10 días // porque el tiempo de operación multitedado puede ser BUF.Append ("threat [") .Append.Append. Stuck-> ") .Append (Procc/1000f) .Append (" S/N ") .Append (" Ejecutar tarea: ") .Append (actualThread.getLastCommand.getClass.getName); try {stacktraceElement elements = currentThread.getStackAntAn .Append (Elements [i] .getClassName) .Append (".") .Append (Elements [i] .getMethodName) .Append ("("). Append (Elements [i] .getFileName) .Append (";"). Append (Elementos [i] .getLinEnuminer) .Append (")"); }} capt (excepción e) {buf.append (e); } buf.append ("/n ++++++++++++++++++++++++++++++++++++++++++"); }} Cadena toString = buf.ToString; if (! StringUtil.isNullorEmpty (toString)) {log.error (toString); if (system.CurrentTimemillis-dastsendMail> 5 * 60 * 1000) {dastSendMail = system.currentTimillis; mailutil.sendMail ("la ejecución de subproceso está Stuck-> gameid--" + objecgleBal.geGameid + " +" Toorleid " +" + " +" + "Toorleid" ObjectGlobal.platform + "ID de servidor-" + ObjectGlobal.ServerId, toString); }}} // </editor-fold> @Override public void run {myThread currentThread = (myThread) thread.currentThread; while (runing) {while (taskqueue.isempty && running) {try {/* La cola de tareas está vacía, entonces una nueva tarea está esperando que una nueva tarea se una y se despierta*/sincronizada (tarea) {taskqueue.wait (500); }} capt (interruptedException es decir) {log.error (es decir); }}/* Obtenga la tarea para ejecutar*/if (runing) {currentthread.lastCommand = null; currentthread.lastCommand = taskqueue.poll; } if (currentThread.lastCommand! = null) {if (currentThread.lastCommand.iscancel) {// Si la tarea se ha cancelado continúa; }/* Ejecutar la tarea* /// R.SetSubMitTimel; currentThread.LastexecUTETime = System.CurrentTimemillis; intente {currentThread.lastCommand.run;} Catch (excepción e) {log.error ("trabajador <" + currentThread.getNeM se encontró un error: ", e); } long timel1 = System.CurrentTimemillis - CurrentThread.LastexecutTime; if (timel1 <= 20) {} else if (timel1 <= 100l) {log.info ("trabajador <" " + currentThread.getName +"> "completó la tarea:" + currentThread.lastCommommand.ToString + "Time de ejecución:" + Timel1);} el más if (Timel1 <= = = 200l) {log.info ("Worker <" "" "" "SUCTURY" "SUNTURA + THETTEM ""> Ejecución a largo plazo de la finalización de la tarea: " + currentThread.lastCommand.ToString +" "Considere" la lógica de secuencia de comisiones de tarea: " + timel1);} else {log.info (" trabajador <"" + actualthread.getName + "> Ejecutar finalización de la tarea durante un tiempo largo:" Currentthread.LastCOMAND.TOSTROMTER + "Ejecutar la finalización de la tarea durante un tiempo largo:" CurrentThread.LastCOMAND.TOSTRIMIENT eliminado "El script de tarea que consume el tiempo:" + Timel1); } currentThread.LASTEXECUTETime = 0; }} log.error ("Hift Ends, Worker <" " + Thread.CurrentThread.getName +" "> EXIT"); } / *** hilo personalizado* / public class myThread extiende el hilo { / **** @param tid ID de subproceso personalizado* @Param Group Group* @param ejecutar el método de ejecución* @param nombre de hilo de nombre* / public mythread (long tid, grupo de grupo, grupo ejecutable, ejecución, nombre de cadena) {super (grupo, ejecución, nombre, nombre); this._id = tid; } // ID personalizado de Thread Public Long _id; // Tarea de ejecución pública Volátil Taskevent LastCommand; // tiempo para comenzar a ejecutar la tarea pública volátil durante mucho tiempo lastexecutetime = 0; Public Taskevent GetLastCommand {return LastCommand; } public Long getLastexecutetime {return lastExecutTime; } / ** * return hilo personalizado ID * * @return * / @Override public Long getid {return _id; }} / *** Detén el hilo, configure el estado de parada del hilo y no terminará el hilo inmediatamente* / public void stop {this.runing = false; } public boolean isruning {return running; } @Override public String toString {return "hilo {" + "tid =" + tid + ", name =" + this.getName + '}'; }}
Construí a partir de ThreadModel
public ThreadModel (grupo ThreadGroup, nombre de cadena, int ThreadCount, runnable runnable) {SynChronized (syn_object) {threadid ++; tad = 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, grupo, runnable, nombre + "-" + tid + "-" + i); } thread.start; hilts.add (hilo); } this.name = name; }Como se puede ver, aquí ejecuto la clase de hilo mythread declarada
¿Por qué pienso en esto? Por ejemplo, si estoy procesando datos de escritura de registro, como sin datos compartidos, y sin flujo de procesamiento de área crítica de subprocesos, puedo considerar usar n hilos para procesar dicho trabajo; No producirá datos sucios;
Si quiero unir y solicitar el lanzamiento de habilidades, necesito procesar una sola cola, entonces solo debe haber un mythread en ThreadModel. Esto no cuenta como ejecución en serie del modo de bloqueo (o ejecución de la cola) para resolver el problema de compartir datos y un área crítica de subprocesos, que ya no depende de los bloqueos;
Soy muy feo, por favor perdóname
Como se muestra en la imagen de arriba, habrá dos colas en cada Modelo de Thread, un TimetAskent y el otro TaskVent, y habrá un hilo de temporizador global;
La función del hilo del temporizador global es procesar y descubrir que el TimetAskent en ThreadModel debe ser ejecutado, por lo que se agrega al equipo TaskVent; La ejecución final es la cola de taskvent
¿Por qué se debe almacenar el tiempo de tiempo en el model de roscas correspondiente? Esto se debe a que, por ejemplo, después de que mi hilo se ejecuta una (instancia de TreadModel) durante un período de tiempo, necesito cerrar y liberar recursos, por lo que tengo que ir a otros lugares para encontrar la tarea de horario correspondiente y eliminarla;
paquete net.sz.engine.thread; import java.util.hashmap; import java.util.map;/** * * <br> * Programador del autor cayendo <br> * correo [email protected] <br> * teléfono 13882122019 <br> */class TimerThread extiende el hilo {Objeto estático privado Syn_Object = nuevo objeto nuevo; 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; valor.timerrun; }}}}
Administrador de modelos de hilo
paquete 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.globtimevent; import.sz.ingine.timer.timer.timer.printlnserververververvent; org.apache.log4j.logger;/** * Manager de hilos * * <br> * Autor Falló programador <br> * Correo [email protected] <br> * teléfono 13882122019 <br> */public class Threadpool {Logger final privado estático Logger = logger.getLogger (threadpool.class); Público estático final Long Globlthread; TimerThreadGloBlTimerthread de TimerThRoBlEmTrIl de TimerL de TimerToBlEBL de estática; Final estático Long LongThreadTimerThreadModel; static public final Threadgroup globlThreadGroup = new ThreadGroup ("Global ThreadGroup"); STACIT Public Final ThreadGroup desconocidoThreadGroup = new ThreadGroup (GloBlThreadGroup, "Desconocido de grupo ThreadGroup"); Final privado estático final de Concurrenthashmap <long, ThreadModel> ThreadMap = nuevo concurrenthashmap <>; public static void main (string [] args) {threadpool.addtimerTask (GloblThread, new TimeRTASKEVENT (1000) {@OverridePublic Void run {log.error ("SSSSS");}}); } static {// crea el hilo global globlThread = addThreadModel (GloblThreadGroup, "GloblThread"); // Ejecute el tiempo de tarea especificado para activar los pasos addTimerTask (GloblThread, new GlobtimerEvent (scriptManager.getInstance.getBasscriptEntry)); // Consulta el modelo de sincronización de consumo de servidor AddTimerTask (GloblThread, new PrintlnServerMemoryTimerEvent); // Crear el hilo de temporizador globltimerThread = new TimerThread; GLOBLTIMERTHREAD.Start; // verifique el hilo atascado checkThreadTimerthreadModel = addThreadModel (GloblThreadGroup, "Check ThreadTimer Event"); addTimerTask (checkThreadTimerThreadModel, nuevo checkThreadTimerEvent); } / ** * Al eliminar el modelo de hilo de ID especificado, establezca el estado en el estado de parada * * @param tid * @return * / static public threadmodel eliminar (long tid) {threadmodel remove = threadmap.remove (tid); if (eliminar! = null) {remove.stop; } return eliminar; } / ** * Obtenga todos los hilos en el grupo de subprocesos * * @return * / static public concurrenthashmap <long, threadmodel> getThreadMap {return threadmap; } / ** * Obtenga un hilo en el grupo de subprocesos * * @param threadid * @return * / static public threadmodel getThreadModel (long threadid) {threadmodel get = threadmap.get (threadid); if (get == null) {log.error ("no se puede encontrar el modelo de subproceso:" + threadid, nueva excepción ("modelo de hilo no se puede encontrar:" + threadid)); } return get; } / ** * Registre un hilo en el grupo de subprocesos * <BR> * Agrupación predeterminada Desconocido de LEADGROUP * * @Param Nombre de hilo * @Return * / static public long addThreadModel (name de cadena) {return addThreadModel (desconocido threadgroup, nombre); } / ** * Registre un hilo en el grupo de subprocesos * <br> * Agrupación predeterminada Desconocido de LEADGROUP * * @param Name ThreadName * @param ThreadCount ThreadCount * @Return * / Static public Long AddThreadModel (name de cadena, int ThreadCount) {return addThreadModel (desconocido THELETGROUP, Nombre, ThreadCount); } / *** Registre un hilo con el grupo de subprocesos** @Param Group Información de agrupación de hilo* @param nombre de hilo* @return* / static public long addThreadModel (grupo ThreadGroup, nombre de cadena) {return addThreadModel (grupo, nombre, 1); } / *** Registre un hilo con el grupo de subprocesos** @Param Group Información de agrupación de hilo* @param nombre ThreadName* @param ThreadCount ThreadCount* @return* / static public Long AddThreadModel (grupo ThreadGroup, name de cadena, int ThreadCount) {return addThreadModel (grupo, nombre, null, threadcount); } / *** Registre un hilo con el grupo de subprocesos** @Param Información del grupo de subproceso* @param name ThreadName* @param runnable* @param ThreadCount ThreadCount* @Return* / static public Long AddThreadModel (grupo ThreadGroup, name, runnable runnable, int threadcount) {ThreadModel ThreadModel = new ThreadModel (grupo, name, name, runnable runnable, int threadcount) return addThreadModel (ThreadModel); } / ** * Registre un hilo con el grupo de subprocesos * * @param threadmodel * / static public long addThreadModel (ThreadModel ThreadModel) {ThreadMap.put (ThreadModel.getID, ThreadModel); return threadmodel.getId; } / ** * Agregar tarea * * @param threadid * @param tarea * @return * / static public boolean addTask (Long Threadid, tarea de Taskevent) {ThreadModel ThreadModel = getThreadModel (ThreadID); if (threadmodel! = null) {threadmodel.addtask (tarea); return true; } return false; } / ** * Agregar tarea de temporizador * * @param threadid * @param task * @return * / static public boolean addTimerTask (Long Threadid, TimeTASKevent Task) {ThreadModel ThreadModel = getThreadModel (ThreadId); if (threadmodel! = null) {threadmodel.addtimer (tarea); return true; } return false; } / ** * Agregar tarea, Agregar tarea al hilo actual * * @param tarea * @return * / static public boolean addCurrentThreadTask (tarea de taskevent) {hilo actual de thread = thread.currentThread; if (actitudThread instancia de ThreadModel.MyThread) {Long ThreadId = CurrentThread.getID; ThreadModel ThreadModel = GetThreadModel (ThreadID); if (ThreadModel! = NULL) {ThreadModel.addtask (tarea); return True; }} return false; } / ** * Agregue una tarea de temporizador y agregue una tarea al subproceso actual * * @param tarea * @return * / static public boolean addCurrentThreadTimeTTask (tarea de timerTASKEVEVE) {hilo de hilo actual = thread.currentThread; if (actitudThread instancia de ThreadModel.MyThread) {Long ThreadId = currentThread.getId; ThreadModel ThreadModel = getThreadModel (ThreadID); if (ThreadModel! = NULL) {ThreadModel.addtimer (tarea); return True; }} return false; }}
A continuación, echemos un vistazo al uso
Código de introducción de hilo en el artículo anterior
public static void main (string [] args) lanza interruptedException {// paralelismo de hilos, múltiples hilos ejecutan múltiples tareas/funciones new Thread (new run1) .Start; nuevo hilo (nuevo Run2) .Star; } // tarea1 clase static run1 implementa runnable {@Override public void run {// ejecutar tarea 1 run1; // ejecutar tarea 3 run3; }} // tarea2 clase static run2 implementos runnable {@Override public void run {// ejecutar tarea 3 run3; // ejecutar tarea 1 run1; // ejecutar tarea 2 run2; }} // Tarea 1 public static void run1 {system.out.println ("run1->" + system.currentTimemillis); } // tarea 2 public static void run2 {System.out.println ("run2->" + System.CurrentTimemillis); } // tarea 3 public static void run3 {System.out.println ("run3->" + System.CurrentTimemillis); }Cambié el código al modo
public static void main (string [] args) lanza interruptedException {// Los hilos son paralelos, múltiples hilos ejecutan múltiples tareas/funciones long test1 = threadpool.addthreadmodel ("test hilo-1"); Long test2 = Threadpool.addthreadModel ("Test Thread-2"); // agregar tarea threadpool.addtask (test1, nueva run1); Threadpool.addtask (test2, new run2); // Agregar tarea de temporizador Threadpool.addTimerTask (test1, new TimerRun1); Threadpool.addtimerTask (test2, new timerrun2); } // Tarea1 La clase static run1 extiende Taskevent {@Override public void run {// Ejecutar tarea 1 run1; // ejecutar tarea 3 run3; }} // Task1 La clase estática Timerrun1 extiende TimeRTASKEVEVE {public TimErRun1 {super (500); // 500ms Ejecución ilimitada} @Override public void run {// ejecutar tarea 1 run1; // ejecutar tarea 3 run3; }} // tarea2 class static run2 extiende taskevent {@Override public void run {// ejecutar tarea 3 run3; // ejecutar tarea 1 run1; // ejecutar tarea 2 run2; }} // Task2 La clase estática TimErRun2 extiende TimeRTASKEVEVE {public timErRun2 {super (500); // 500MS Ejecución ilimitada} @Override public void run {// ejecutar tarea 3 run3; // ejecutar tarea 1 run1; // ejecutar tarea 2 run2; }} // tarea1 public static void run1 {system.out.println ("run1->" + system.currentTimemillis); } // tarea2 public static void run2 {System.out.println ("run2->" + System.CurrentTimemillis); } // tarea 3 public static void run3 {System.out.println ("run3->" + System.CurrentTimemillis); }A continuación, echemos un vistazo al efecto de ejecución
Run1-> 1472120543013run3-> 1472120543013run3-> 1472120543017run1-> 1472120543017run2-> 14721205 43017run1-> 1472120543517run3-> 1472120543517run2-> 1472120543517run1-> 1472120544018run3-> 1477 2120544018run2-> 1472120544018run1-> 1472120544520run3-> 1472120544520run2-> 1472120544520run1 -> 1472120545021run3-> 1472120545021run2-> 1472120545021run1-> 1472120545521run3-> 14721205455521
Todo es normal;
Este es mi modelo de subproceso personalizado;
En este punto, se ha completado mi modelo de roscado personalizado;
Entonces, ¿cuáles son las ventajas y desventajas?
La ventaja es que el control del flujo de datos es muy claro, incluida la situación de ejecución actual, así como los subprocesos de monitoreo y la ejecución del temporizador de tareas;
Desventajas, este modelo de hilo personalizado aún no puede resolver el problema de la seguridad de los datos de los subprocesos y el área crítica, y aún debe resolverse mediante bloqueos u otras formas en el momento apropiado;
Espero que los grandes dioses señalen las deficiencias, para que pueda corregirlas de inmediato.