Diejenigen, die meine vorherigen Artikel gelesen haben, wissen möglicherweise, dass ich Spieleentwicklung mache. Viele meiner Ideen und Ausgangspunkte werden nach Spielideen behandelt, sodass möglicherweise Konflikte mit dem Web bestehen und nicht im Einklang damit stehen.
Lassen Sie mich Ihnen sagen, warum ich das Thread -Modell anpassen möchte?
Gemäß dem MMORPG- oder MMORPG -Spiel, das ich erstellt habe, sind die Threads in Hauptthread, globaler Synchronisations -Thread, Chat -Thread, Team -Thread, Karten -Thread und Kartennachrichtenverteilung und Lieferung usw. unterteilt.
Einige Spalten müssen gemäß meinem Teilungs- und Datenfluss gesteuert werden.
Die Hauptsache auf dem Spielserver ist es, die Befehlsanforderung des Spielers zu akzeptieren -> entsprechende Operation -> das Ergebnis zurückgeben.
Alle Nachrichten auf der Serverseite werden im Message Manager registriert, und dann wird das Thread -Modell angegeben, wenn die Nachricht registriert ist.
Wenn die Nachricht zur Verarbeitung in den Karten -Karten -Thread des Players übermittelt werden muss, müssen Sie beim Registrieren der Nachricht das Thread -Modell verwenden (Kartenmeldungsverteilung und Versand -Thread).
Lassen Sie uns zunächst das Thread -Modell analysieren.
Bevor ich mir den Thread -Modellcode ansehe, schaue ich mir zuerst mein Aufgabenmodell an
Paket net.sz.engine.thread; import Java.io.Serializable; import org.apache.log4j.logger; net.sz.engine.structs.ObjectTribute; net.sz.engine.structs.ObjectGlobal; 13882122019 <br> */public abstract Class Taskevent implementiert serialisierbare, klonbare {private statische endgültige Logger -Log = logger.getLogger (taskevent.class); Private statische endgültige lange Serialversionuid = 419602065994845804L; // Laufzeitdaten private transiente endgültige ObjectAtTribute runoth = new ObjectAtTribute; // Aufgabenerstellung Zeit geschützt long CreateTime; // Aufgabe eindeutig ID geschützt Long TaskId; // Stornierte Aufgabe geschützt boolean cancel = false; public taskevent {this.runother.put ("Subletime", System.currentTimemillis); CreateTime = System.currentTimemillis; abbrechen = false; TaskID = ObjectGlobal.getuUid; } public Long GetCreateTime {return CreateTime; } public void setCreateTime (Long CreateTime) {this.createTime = CreateTime; } public long getsubmitTime {return this.runother.getLongValue ("Subletime"); } public ObjectAttribute getRunother {return runoth; } public boolean iscancel {return cancel; } public void setCancel (boolean cancel) {this.cancel = cancel; } public abstract void Run; @Override Public Object Clone löscht ClonenotsupportedException {return Super.clone; // Wählen Sie Tools | Vorlagen. }}Paket net.sz.engine.thread;/** * Timer Executor * * <br> * Autor fehlgeschlagener Programmierer <br> * Mail [email protected] <br> * Telefon 13882122019 <br> */public Abstract Class TimertaskevEvent erweitert TaskeVent {private statatatatik. / *** Zeit für die Ausführung*/ geschütztes langes Startzeit; / *** ob am Anfang einmal ausgeführt werden soll*/ geschützter boolescher StartAction; / *** Endzeit*/ geschützte lange Endzeit; / *** Anzahl der Ausführungen*/ Protected Int ActionCount; / *** Intervallausführungszeit*/ Protected Int -IntervalimTime; / **** @param starttime Geben Sie die Startzeit an* @param isStartAction, ob Sie zu Beginn einmal ausgeführt werden sollen this.starttime = startTime; this.startaction = isStartaction; this.endTime = endzeit; this.actionCount = actionCount; this.Intervaltime = Intervaltime; } / *** Geben Sie die Ausführungszeit der Aufgabe an** @param StartTime Geben Sie die Startzeit an* @param isStartAction, ob sie zu Beginn einmal ausgeführt wird. actionCount, IntervALTime); } / *** Die angegebene Endzeit ist die Endzeit, und die Anzahl der Ausführungen ist nicht unbedingt ausreichend** @param isStartAction, ob Sie zu Beginn einmal ausgeführt werden sollen Dies (0, isStartaction, Endtime, ActionCount, Intervaltime); } / *** Geben Sie die Startzeit und die Endzeit an** @param StartTime Geben Sie die Startzeit an* @param endzeit an. } / *** angegebene Ausführungszeiten und Intervallzeit** @param actionCount Geben Sie die Anzahl der Ausführungen an* @Param IntervALTime Geben Sie die Intervallzeit an* / public timerTasKevent (int actionCount, int intervalaTime) {this (0, false, 0, actionCount, Intervalous); } / *** Unbegrenzte Ausführung nach Einreichung* @Param IntervALTime angegebene Intervallzeit* / public timerTasKevent (int IntervALTime) {this (0, false, 0, -1, IntervALTime); } public Long GetStartTime {return start time; } public void setStartTime (Long Start Time) {this.startTime = StartTime; } public boolean isStartAction {return startAction; } public void setStartAction (boolean startAction) {this.StartAction = StartAction; } public long getendTime {return Endtime; } public void setendTime (lange Endzeit) {this.endTime = endzeit; } public int getActionCount {return actionCount; } public void setActionCount (int actionCount) {this.actionCount = actionCount; } public int getIntervaltime {Rückgabeintervaltzimperatur; } public void setIntervaltime (int intervalaTime) {this.intervaltime = Intervaltime; }}
Hier sind das Aufgabenmodell und das Timer -Aufgabenmodell.
Paket net.sz.engine.thread; import Java.util.ArrayList; Import Java.util.List; Import Java.util.Concurrent org.apache.log4j.Logger;import org.jboss.jandex.Main;/** * Thread Model* <br> * author Failed Programmer<br> * mail [email protected]<br> * phone 13882122019<br> */public class ThreadModel implements Runnable { private static final Logger log = Logger.getLogger (ThreadModel.Class); private statische lange ThreadID = 0; geschütztes statisches endgültiges Objekt syn_Object = neues Objekt; geschützte lange Zeit; geschützter String -Name; geschützt long lastSendmail = 0; Protected Final ArrayList <MyThread> threads = new ArrayList <>; /*** Taskliste Thread-Safe-Taskliste*/// Abschließende Liste <TaskModel> TaskQueue = New ArrayList <>; geschütztes endgültiges gleichzeitiges LinkedQueue <Taskevent> taskQueue = new ConcurrentLinkedQueue <>; / ***/ Protected Final List <TimerTasKevent> Timerqueue = new ArrayList <>; // falsche Identität löschen Gewinde geschützte flüchtige boolean running = true; public threadModel (ThreadGroup -Gruppe) {this (Gruppe, "no name", 1); } public threadModel (String -Name) {this (threadpool.unnownThreadGroup, Name, 1); } public threadModel (ThreadGroup -Gruppe, String -Name, int threadCount) {this (Gruppe, Name, ThreadCount, NULL); } public threadModel (ThreadGroup -Gruppe, 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; } / ** * Threadname * * @return * / public String getName {return name; } / ** * Die benutzerdefinierte ID des Threads erhalten * * @return * / public Long getid {return this.tid; } / ** * Fügen Sie für jede neue Aufgabe eine neue Aufgabe hinzu, die Task -Warteschlange muss erweckt werden * * @param runnable * / public void addtask (Taskevent Runnable) {TaskQueue.add (runnable); Synchronized (TaskQueue) {/ * Weck die Warteschlange auf und starten Sie die Ausführung */ taskQueue.notifyAll; }}/** * Fügen Sie dem Thread eine Timer -Aufgabe hinzu * * @param runnable */public void addtimer (timertasKEvent runnable) {synchronized (timerqueue) {if (runing) {// einmal am Anfang (runnable.startAction) {addtask (runnable); } Timerqueue.add (runnable);} else {log.Error ("Thread hat gestoppt"); }}}} // <editor-fold defaultState = "collapsed" Desc = "Timer Thread Executor public void timerrun"> / *** Timer Thread Executor* / public void Timerrun {ArrayList <TimerTasKEVENT> TaskModels; Synchronized (Timerqueue) {// Wenn die Warteschlange nicht leer ist, nehmen Sie die Warteschlangen TaskModels = new ArrayList <> (Timerqueue) heraus; } if (! taskmodels.isempty) {for (timerTasKevent timerevent: taskModels) {int execcount = timerevent.getrunother.gettinValue ("execCount"); lange lastTime = Timerevent.getRunother.getLongValue ("lastExectime"); Long Time Time = System.currentTimemillis; if (lastTime == 0) {Timerevent.getRunother.put ("lastExectime", Now Time);} else if (timerevent.iscancel) {// Wenn die Aufgabe synchronisiert wurde (Timerqueue) {Timerqueue.Remove (TimeRevent); } log.debug ("Die Timer -Aufgabe reinigen:" + timerevent.getClass.getName);} else if (time> timerevent Timerevent.getendTime) // Bestimmen Sie die Endzeit && (Now Time - lastTime> = Timerevent.getIntervaltime)) // Bestimmen Sie, ob die Intervallzeit seit der letzten Ausführung erfüllt wurde. execCount); timerevent.getRunother.put ("lastExectime", NowTime); NowTime = System.currentTimemillis; // Bestimmen Sie die Deletionsbedingung if (timerevent.getendTime> 0 && nowTime Timerqueue.Remove (TimereEvent); } log.debug ("Reinigungs -Timer -Aufgabe:" + timerevent.getClass.getName); }}}}}}} // </editor-fold> // <editor-fold defaultState = "Collapsed" Desc = "Thread Stack public void showstacktrace">/**** Thread Stack ansehen*/public void showstacktrace {stringbuilder buf = new Stringbuilder; Für (MyThread CurrentThread: Threads) {Long Procc = System.currentTimemillis - CurrentThread.getLastexecUTetime; if (procc> 5 * 1000 && procc <86400000l) {// weniger als 10 Tage //, weil die MultitHe -Operation -Zeit möglicherweise nicht buf.append ("thread (" thread ("thread ("). stecken-> ") .Append (procc/1000f) .Append (" s/n ") .Append (" Task ausführen: ") .Append (currentThread.getLastCommand.getClass.getName); Versuchen Sie {StackTraceElement Elements = current.getStacktrace; .Append (Elemente [i] .GetClassName) .Append (".") .Append (Elemente [i] .getMethodname) .Append ("("). Append (Elements [i] .GetFileName) .Append (";"). Append (Elements [i] .GEGLINENUMN) .Append ("))"); }} catch (Ausnahme e) {buf.append (e); } buf.append ("/n ++++++++++++++++++++++++++++++++"); }} String toString = buf.toString; if (! Stringutil.isnullorempy (toString)) {log.Error (toString); if (system.currentTimillis-lastSendmail> 5 * 60 * 1000) {lastsendmail = system.currenttimemillis; mailUtil.sendmail ("Thread Execution steckt" + " +. ObjectGlobal.Platform + "Server ID-" + ObjectGlobal.Serverid, toString); }}} // </editor-fold> @Override public void run {MyThread CurrentThread = (MyThread) Thread.CurrentThread; while (runing) {while (TaskQueue.isempty && running) {try {/* Die Task -Warteschlange ist leer, dann wartet eine neue Aufgabe darauf, dass eine neue Aufgabe beitritt und aufgeweckt wird*/synchronisiert (TaskQueue) {TaskQueue.wait (500); }} catch (InterruptedException IE) {log.Error (dh); }}/* Die Aufgabe zur Ausführung*/if (runing) {currentThread.lastcommand = null; currentThread.lastcommand = taskQueue.poll; } if (currentThread.lastcommand! }/* Die Aufgabe ausführen* /// r.setsubmittimel; currentThread.lastexecutetime = system.currentTimemillis; try {currentThread.lastcommand.run;} catch (Ausnahme E) {Log.error ("Worker <" + currentThread.getname + "> AUFURDE Die Aufgabe. wurde begegnet: ", e); } Long Timel1 = System.currentTimemillis - CurrentThread.lastexecutetime; if (Timel1 <= 20) {} else if (Timel1 <= 100l) {log.info ("Worker <" " + currentThread.getName +" "> Die Aufgabe abgeschlossen:" + currentThread.lastcommand.toString + "Ausführungszeit:" + Timel1); "> Langfristige Ausführung des Abschlusses der Aufgabe:" + currentThread.lastcommand.toString + "" "" "In Betracht" des Task-Skripts logisch zeitaufwändig: " + timel1);} else {log.info (" Worker <"" + CurrentThread.getName + "> Ausführungsvervollständigung. gelöscht "Das Task-Skript zeitaufwändig:" + Timel1); } currentThread.lastexecutetime = 0; }} log.Error ("Thread endet, Worker <" " + thread.currentThread.getName +" "> exit"); } / *** benutzerdefinierter Thread* / public class myThread erweitert Thread { / **** @param TID benutzerdefinierte Thread -ID* @param Group Group* @param Run Execution -Methode* @param Name Thread Name* / public myThread (Long Tid, ThreadGroup Group, Runnable Run, String -Name) {Super (Gruppe, Run, Name); this._id = tid; } // benutzerdefinierte ID von Thread Public Long _id; // Ausführungsaufgabe öffentlich volatile Taskevent lastcommand; // Zeit für die Ausführung der Aufgabe öffentlich volatile lastExecutetime = 0; public taskevent getLastcommand {return lastCommand; } public Long getLastExecutetime {return lastExecutetime; } / ** * thread benutzerdefinierte id * * @return * / @Override public Long getId {return _id; }} / *** Stoppen Sie den Thread, setzen Sie den Stop -Status des Threads und beenden Sie den Thread nicht sofort* / public void stop {this.runing = false; } public boolean isruning {return running; } @Override public String toString {return "thread {" + "tid =" + tid + ", name =" + this.getName + '}'; }}
Ich habe aus Threadmodel konstruiert
public ThreadModel (ThreadGroup -Gruppe, Zeichenfolge 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; }Wie zu sehen ist, leite ich hier die myThread -Thread -Klasse, die deklariert ist
Warum denke ich darüber nach? Wenn ich beispielsweise Protokoll -Schreibdaten wie keine gemeinsam genutzten Daten und keinen Verarbeitungsfluss für den Thread -Critical Area verarbeite, kann ich in Betracht ziehen, N -Threads zu verarbeiten, um solche Arbeiten zu verarbeiten. Es wird keine schmutzigen Daten erzeugt;
Wenn ich mich zusammenschließen und Skills Casting anfordern möchte, muss ich eine einzelne Warteschlange verarbeiten, dann muss es nur ein MyThread in ThreadModel geben. Dies gilt nicht als die serielle Ausführung (oder Warteschlangenausführung) der Blockierungsmodus, um das Problem der Freigabe von Daten und dem kritischen Bereich von Threads zu lösen, der nicht mehr von Sperren abhängt.
Ich bin sehr hässlich, bitte vergib mir
Wie im obigen Bild gezeigt, gibt es in jedem Threadmodel zwei Warteschlangen, ein Timetaskevent und das andere nachgedacht, und es wird einen globalen Timer -Thread geben.
Die Funktion des globalen Timer -Threads besteht darin, zu verarbeiten und festzustellen, dass das Timetaskevent im ThreadModel ausgeführt werden muss, sodass es dem Taskvent -Team hinzugefügt wird. Die endgültige Ausführung ist die Haftwarteschlange
Warum sollte Timetaskevent im entsprechenden Threadmodel gespeichert werden? Das liegt daran, dass ich zum Beispiel nach meinem Thread A (ThreadModel -Instanz) für einen bestimmten Zeitraum die Ressourcen schließen und frei machen muss, damit ich zu anderen Orten gehen muss, um den entsprechenden Zeitpunkt zu finden und zu entfernen.
Paket net.sz.engine.thread; import java.util.hashMap; import Java.util.map;/** * <br> * Autor falls Programmierer <br> * mail 492794628@qqq 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 <lang, threadmodel> Hashmap = new Hashmap <> (threadpool.getTheadMap); for (map.entry) (threadpool.getheadmap); for (map.entry, threadmodel. HashMap.EntrySet) {long key = EintragsetKey; ThreadModel value = Eintragset.getValue; Value.Timerrun; }}}}Thread Model Manager
Paket net.sz.engine.thread; import java.util.hashMap; import Java.util.concurrent org.apache.log4j.logger;/** * Thread Manager * * <br> * Autor fehlgeschlagener Programmierer <br> * Mail [email protected] <br> * Telefon 13882122019 <br> */public class threadpool {static private endgültige logger Log = Logger.getlogger (threadpool.classe); statische öffentliche letzte lange GloblThread; statische private endgültige TimerThreadGlobltimerThread; statische letzte lange CheckthreadtimerThreadmodel; statische öffentliche endgültige Threadgroup GloblThreadGroup = New ThreadGroup ("Global Threadgroup"); statische öffentliche endgültige Threadgroup Unknownthreadgroup = neue Threadgroup (GloblthreadGroup, "Unbekannte Threadgroup"); statische private endgültige Concurrenthashmap <lang, ThreadModel> ThreadMap = Neue Concurrenthashmap <>; public static void main (String [] args) {threadpool.addTimerTask (GloblThread, New TimertasKevent (1000) {@OverridePublic void run {log.Error ("sssss");}}); } static {// Erstellen Sie den globalen Thread GloblThread = addthreadmodel (GloblThreadGroup, "GloblThread"); // Führen Sie das angegebene Aufgabe -Timing aus, um die Fußstapfen -AddTimerTask (GloblThread, New GlobeTimereEvent (scriptManager.getInstance.getBaseScriptEntry)) auszulösen. // Abfragen Sie das Serververbrauch Timing -Modell AddTimerTask (Globlthread, New PrintlnServerMemoryTimeTimerEvent); // Erstellen Sie den Timer -Thread GlobltimerThread = New TimerThread; GlobltimerThread.Start; // Überprüfen Sie den Thread Stuck CheckThreadTimeThreadModel = AddthreadModel (GloblthreadGroup, "ThreadTimer -Ereignis"); addTimerTask (checkthreadtimerThreadmodel, neuer CheckthreadTimeRevent); } / ** * Beim Löschen des angegebenen ID -Threadmodells den Status auf den Stop -Status festlegen * * @param TID * @Return * / static publicModel Remove (Long TID) {ThreadModel REMED = THEMMAP.REMOVE (TID); if (entfernen! = null) {entry.Stop; } return entfernen; } / ** * Alle Threads in den Thread -Pool erhalten * * @return * / static public ConcurrentHasMap <lang, ThreadModel> getThreadmap {return threadMap; } / ** * einen Thread in den Thread -Pool erhalten * * @param threadId * @return * / static publicModel getThreadmodel (langer ThreadID) {ThreadModel get = ThreadMap.get (ThreadID); if (get == null) {log.Error ("Das Thread -Modell kann nicht gefunden werden:" + ThreadID, neue Ausnahme ("Threadmodell kann nicht gefunden werden:" + threadId)); } return get; } / ** * Registrieren Sie einen Thread mit dem Thread -Pool * <br> * Standardgruppierung unbekannt ThreadGroup * * @param Name Thread Name * @return * / static public Long Addthreadmodel (String -Name) {return addthreadmodel (unbekannte Threadgroup, Name); } / ** * Registrieren Sie einen Thread mit dem Thread -Pool * <br> * Standardgruppierung unbekannt ThreadGroup * * @param Name ThreadName * @param threadCount threadCount * @return * / static public Long AddMthreadModel (String -Name, int threadCount) {return addthreadmodel (unbekannte ThreadGroup, Name, ThreadCount); } / *** Registrieren Sie einen Thread mit dem Thread -Pool** @param Group -Thread -Gruppierungsinformationen* @param Name Threadname* @return* / static public long addthreadmodel (ThreadGroup -Gruppe, String -Name) {return addthreadmodel (Gruppe, Name, 1); } / *** Registrieren Sie einen Thread mit dem Thread -Pool** @param Group -Thread -Gruppierungsinformationen* @param name threadName* @param threadCount threadCount* @return* / static public Long Addthreadmodel (ThreadGroup -Gruppe, String -Name, int ThreadCount) {return addthreadmodel (Gruppe, Name, Null, ThreadCount, ThreadCount); } /** * Register a thread with the thread pool* * @param group Threadgroup information* @param name Threadname* @param runnable * @param threadcount 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); } / ** * Registrieren Sie einen Thread mit dem Thread -Pool * * @param ThreadModel * / static public Long AddThreadModel (ThreadModel ThreadModel) {ThreadMap.put (ThreadModel.getID, ThreadModel); return threadmodel.getId; } / ** * Aufgabe hinzufügen * * @param threadID * @param task * @return * / static public boolean addtask (langes ThreadID, Taskevent Task) {ThreadModel ThreadModel = getThreadModel (ThreadID); if (threadModel! } return false; } / ** * Timer -Task hinzufügen * * @param threadID * @param task * @return * / static public boolean addTimerTask (Long ThreadID, TimertasKevent Task) {ThreadModel ThreadModel = getThreadModel (ThreadID); if (threadModel! } return false; } / ** * Aufgabe hinzufügen, die Aufgabe zum aktuellen Thread hinzufügen * * @param task * @return * / static public boolean addCurrentThreeTask (Taskevent Task) {Thread CurrentThread = Thread.currentThread; if (currentThread Instance von ThreadModel.mythread) {long ThreadId = currentThread.getId; ThreadModel ThreadModel = getThreadModel (ThreadID); if (ThreadModel! }} return false; } / ** * fügen Sie eine Timer -Aufgabe hinzu und fügen Sie dem aktuellen Thread eine Aufgabe hinzu * * @param task * @return * / static public boolean addCurrentThreadTimerTask (TimertasKevent -Aufgabe) {Thread CurrentThread = Thread.currentThread; if (currentThread Instance von ThreadModel.mythread) {long ThreadId = currentThread.getId; ThreadModel ThreadModel = getThreadModel (ThreadID); if (ThreadModel! }} return false; }}
Schauen wir uns als nächstes einen Blick auf die Verwendung an
Thread -Einführungscode im vorherigen Artikel
public static void main (String [] args) löst InterruptedException {// Thread -Parallelität aus, mehrere Threads führen mehrere Aufgaben/Funktionen neuer Thread aus (neuer Run1) .Start; neuer Thread (neuer Run2) .Start; } // Task1 Static Class Run1 Implements Runnable {@Override public void run {// Task ausführen 1 run1; // Task 3 Run3; }} // Task2 Static Class Run2 Implements Runnable {@Override public void run {// Task 3 run3; // Aufgabe 1 run1; // Task 2 Run2 ausführen; }} // Aufgabe 1 public static void run1 {System.out.println ("run1->" + system.currentTimillis); } // Aufgabe 2 public static void run2 {System.out.println ("Run2->" + System.currentTimemillis); } // Aufgabe 3 public static void Run3 {System.out.println ("Run3->" + System.currentTimemillis); }Ich habe den Code in den Modus umgestellt
public static void main (String [] args) löst unterbrochene Ausnahme aus (// Threads sind parallel. Mehrere Threads führen mehrere Aufgaben aus/Funktion lang test1 = threadpool.addthreadmodel ("Test Thread-1"); Long Test2 = ThreadPool.addthreadmodel ("Test Thread-2"); // Task threadpool.addtask (test1, New Run1) hinzufügen; Threadpool.addtask (test2, New Run2); // Timer Taskpool.addTimerTask (test1, neuer Timerrun1) hinzufügen; Threadpool.addimertask (test2, neuer Timerrun2); } // Task1 Static Class Run1 erweitert Taskevent {@Override public void run {// Task 1 Run1; // Task 3 Run3 ausführen; }} // Task1 statische Klasse TimerRun1 erweitert TimertasKevent {public Timerrun1 {Super (500); // 500MS Unbegrenzte Ausführung} @Override public void run {// Task 1 Run1; // Task 3 Run3 ausführen 3; }} // Task2 Static Class Run2 erweitert Taskevent {@Override public void run {// Task 3 Run3; // Task 1 Run1; // Task 2 Run2 ausführen; }} // Task2 Static Class Timerrun2 erweitert TimertAsKevent {public Timerrun2 {Super (500); // 500Ms Unbegrenzte Ausführung} @Override public void run {// Task 3 run3; // Task 1 Run1; // Task 2 Run2 ausführen. }} // Task1 public static void run1 {System.out.println ("run1->" + System.currentTimemillis); } // Task2 public static void run2 {System.out.println ("run2->" + System.currentTimemillis); } // Aufgabe 3 public static void Run3 {System.out.println ("Run3->" + System.currentTimemillis); }Schauen wir uns als nächstes den Ausführungseffekt an
Run1-> 1472120543013Run3-> 1472120543013Run3-> 1472120543017RUN1-> 1472120543017RUN2-> 14721205 43017Run1-> 1472120543517RUN3-> 1472120543517RUN2-> 1472120543517RUN1-> 1472120544018RUN3-> 1477 2120544018Run2-> 1472120544018RUN1-> 147212054520RUN3-> 147212054520RUN2-> 147212054520RUN1 -> 1472120545021run3-> 1472120545021run2-> 1472120545021run1-> 1472120545521run3-> 1472120545521
Alles ist normal;
Dies ist mein benutzerdefiniertes Threading -Modell;
Zu diesem Zeitpunkt wurde mein benutzerdefiniertes Threading -Modell abgeschlossen.
Was sind die Vor- und Nachteile?
Der Vorteil besteht darin, dass die Datenflussregelung sehr klar ist, einschließlich der aktuellen Ausführungssituation sowie die Überwachung und Task -Timer -Ausführung von Threads.
Nachteile, dieses benutzerdefinierte Threadmodell kann das Problem der Sicherheit der Threaddaten und des kritischen Bereichs immer noch nicht lösen, und es muss weiterhin durch Schlösser oder andere Formulare zum richtigen Zeitpunkt gelöst werden.
Ich hoffe, die großen Götter werden auf die Mängel hinweisen, damit ich sie sofort korrigieren kann.