이전 기사를 읽은 사람들은 내가 게임 개발을하고 있다는 것을 알고있을 것입니다. 내 아이디어와 출발점의 대부분은 게임 아이디어에 따라 처리되므로 웹과 충돌 할 수 있으며 웹과 일치하지 않을 수 있습니다.
스레드 모델을 사용자 정의하고 싶은 이유를 알려 드리겠습니다.
내가 만든 MMORPG 또는 MMORPG 게임에 따르면 스레드는 기본 스레드, 글로벌 동기화 스레드, 채팅 스레드, 팀 스레드, 맵 스레드 및 맵 메시지 배포 및 전달 스레드 등으로 나뉩니다.
일부 열은 내 부서 및 데이터 흐름에 따라 제어해야합니다.
게임 서버에서해야 할 가장 중요한 것은 플레이어의 명령 요청 -> 해당 조작 -> 결과를 반환하는 것입니다.
서버 측의 모든 메시지는 메시지 관리자에 등록되며 메시지가 등록되면 스레드 모델이 지정됩니다.
처리를 위해 메시지를 플레이어의 맵 스레드에 제출 해야하는 경우 메시지를 등록 할 때 스레드 모델 (맵 메시지 배포 및 디스패치 스레드)을 사용해야합니다.
먼저 스레드 모델을 분석하겠습니다.
스레드 모델 코드를보기 전에 먼저 작업 모델을 살펴 봅니다.
Package Net.sz.engine.thread; import java.io.serializable; import org.apache.log4j.logger; import net.sz.sz.engine.structs.objectttribute; import net.sz.engine.structs.objectglobal;/** * 태스크 모델 * <br> * 저자가 떨어지는 프로그래머 <br> * mail 492740444444444444 명입니다. 13882122019 <br> */public Abstract Class Taskevent는 시리얼이즈 가능, 클로닝 가능한 {개인 정적 최종 로거 로그 = logger.getLogger (taskevent.class); 개인 정적 최종 최종 긴 SerialversionUID = 4196020659994845804L; // 런타임 데이터 비공개 과도 최종 대상 객체 runother = new ObjectAttribute; // 작업 생성 시간 보호 긴 CreateTime; // 작업 고유 ID 보호 긴 TaskId; // 취소 된 작업 보호 된 부울 취소 = false; public taskevent {this.runother.put ( "제출 시간", System.CurrentTimeMillis); CreateTime = System.CurrentTimeMillis; 취소 = 거짓; taskId = ObjectGlobal.getUuid; } public long getCreateTime {return createTime; } public void setCreateTime (긴 CreateTime) {this.createTime = createTime; } public long getSubmittime {return this.runother.getLongValue ( "제출 시간"); } public ObjectAttribute getRunother {return runother; } public boolean iscancel {반환 취소; } public void setcancel (부울 취소) {this.cancel = 취소; } 공개 초록 void run; @override public object 클론은 클로네 노츠 업 포트 프레드 렉싱 {return super.clone; // 생성 된 방법의 본문을 변경하려면 도구를 선택하십시오 | 템플릿. }}패키지 net.sz.engine.thread;/** * 타이머 집행자 * * <br> * <br> * 저자 실패 프로그래머 <br> * 메일 [email protected] <br> * 전화 13882122019 <br> */public class timertaskevent는 taskevent {private static final long serialversionuid = -833129696296246920; / *** 실행을 시작하는 시간*/ 보호 된 긴 시작 시간; / *** 처음에 한 번 실행할지*/ 보호 된 부울 시작; / *** 종료 시간*/ 보호 된 장기; / *** 실행 수*/ 보호 된 int ActionCount; / *** 간격 실행 시간*/ 보호 된 int 간격 시간; / **** @param starttime 시작 시간을 지정* @param isstartAction 시작 시간에 한 번 실행할지 여부* @param endtime 실행 수를 지정* @param intervaltime 간격 시간을 지정합니다*/ public timertaskevent (긴 시작, 부울 asstArtaction, 긴 종점, int eptaltime) {int inter actimecount); 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* / public timertaskevent* / public isstartaction, int intertartation, int intertate). ActionCount, IntervalTime); } / *** 지정된 종료 시간은 종료 시간이며, 실행 수가 반드시 충분하지 않습니다* @param isstartAction* @param endtime 종료 시간을 지정* @param actioncount 실행 수를 지정* @param 간격 시간을 지정* / public timertaskevent (부울 arttarcation, 롱 엔드 타임, Int Action) < 이 (0, isstartAction, endtime, actionCount, IntervalTime); } / *** 시작 시간과 종료 시간을 지정** @param starttime 시작 시간을 지정* @param endtime 종료 시간 지정* @param intervaltime 간격 시간을 지정* / public timertaskevent (긴 시작 시간, 긴 종료 시간, int 간격 시간) {this (starttime, false, endtime, -1, intergaltime); } / *** 지정된 실행 시간 및 간격 시간** @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; }}
다음은 작업 모델과 타이머 작업 모델입니다.
패키지 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.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz.sz org.apache.log4j.logger; import org.jboss.jandex.main;/** * 스레드 모델 * <br> * 저자 실패 프로그래머 <br> * Mail [email protected] <br> * 전화 13882122019 <br> */public stride modger log {private strood logger runnable emplements emplements emplements runnable emplical logger.getLogger (ThreadModel.class); 개인 정적 긴 threadid = 0; 보호 된 정적 최종 객체 syn_object = 새 개체; 보호 된 긴 팁; 보호 된 문자열 이름; 보호 된 긴 마지막 센트 메일 = 0; 보호 된 최종 ArrayList <Mythread> 스레드 = New ArrayList <>; /*** 작업 목록 스레드-안전 작업 목록* // 보호 된 최종 목록 <TaskModel> taskqueue = new ArrayList <>; 보호 된 최종 동시 동의 주변 링크 Queue <Taskevent> taskqueue = 새로운 동시 동맥 린드 Queue <>; / ***/ 보호 된 최종 목록 <TIMERTASKEVENT> TIMERQUEUE = NEW ARRAYLIST <>; // 거짓 ID 삭제 스레드 보호 휘발성 부울 런닝 = true; public ThreadModel (ThreadGroup Group) {this (그룹, "이름 없음", 1); } public ThreadModel (문자열 이름) {this (ThreadPool.unkNownthreadGroup, name, 1); } public ThreadModel (ThreadGroup Group, String Name, int ThreadCount) {this (그룹, 이름, ThreadCount, NULL); } public ThreadModel (ThreadGroup Group, String Name, int ThreadCount, Runnable Runnable) {Synchronized (Syn_Object) {ThreadId ++; tid = ridsleD; } for (int i = 1; i <= threadCount; i ++) {mythread 스레드; if (runnable == null) {thread = new Mythread (tid, group, this, name + "-" + tid + "-" + i);} else {thread = new mythread (tid, group, runnable, name + "-" + tid + "; } stread.start; threads.add (스레드); } this.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); 동기화 (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 ( "스레드가 중지되었습니다"); }}}} // <편집기 -Fold DefaultState = "Timer 스레드 실행자 Public Void Timerrun"> / *** 타이머 스레드 실행자* / public void Timerrun {ArrayList <TimerTasKevent> TaskModels; 동기화 된 (Timerqueue) {// 큐가 비어 있지 않으면 큐 타이머 taskmodels = new ArrayList <> (TimerQueue)를 꺼냅니다. } if (! taskModels.isempty) {for (timertAskevent timerevent : taskModels) {int execcount = timerevent.getRunother.getTinValue ( "execcount"); Long Longtime = timerevent.getRunother.getLongValue ( "lastomectime"); long nowtime = system.currenttimillis; if (마지막 시간 == 0) {timerevent.getRunother.put ( "lastempime", nowtime);} else if (timerevent.iscancel) {// 작업이 취소 된 경우 (Timerqueue) {Timerqueue.Remove (timerevent); } log.debug ( "타이머 작업 청소 :" + timerevent.getClass.getName);} else if (nowtime> timerevent.getStartTime // 시작 시간이 충족되는지 && (nowtime -timerevent.getSubmittime> timerevent.getIntervalTime) // (timerevent.getHevent. timerevent.getendTime) // 종료 시간을 결정하고 (nowtime -lasttime> = timerevent.getIntervalTime)) // 마지막 실행 이후 간격 시간이 충족되었는지 여부를 결정합니다. {// 제출 실행 타이머는 가장 먼저 실행하는 것입니다. execcount); execcount); timerevent.getRunother.put ( "lastemectime", nowtime); nowtime = system.currenttimillis; // 삭제 조건을 결정합니다. TIMERQUEUE.REMOVE (TIMEREVENT); } log.debug ( "청소 타이머 작업 :" + timerevent.getClass.getName); }}}}}}}} // </editor-fold> // <editor-fold defaultstate = "audred"desc = "스레드 스택 공개 공개 void showstacktrace">/**** 스레드 스택보기*/public void showstacktrace {StringBuilder buf = new StringBuilder; for (mythread currentthread : streads) {long procc = system.currenttimeMillis -currentthread.getLastExecuteMe; if (procc> 5 * 1000 && procc <86400000L) {// multithreaded 작동 시간이 부정확 할 수 있기 때문에 10 일 미만 // (thread [ "). stuck-> ") .append (procc/1000f) .append ("s/n ") .append ("실행 작업 : ") .append (currentthread.getLastCommand.getCommand.getName); try {stackTraceElement elements = currentthread.getStacktrace; for (int i = 0; i++) {"/n) .Append (요소 [i]. append ( "." }} catch (예외 e) {buf.append (e); } buf.append ( "/n ++++++++++++++++++++++++++++++"); }} 문자열 tostring = buf.tostring; if (! stringUtil.isnullorEmpty (tostring))) {log.error (tostring); if (system.currenttimeMillis-lastSendMail> 5 * 60 * 1000) {LastSendMail = System.CurrentTimeMillis; mailutil.sendmail ( "스레드 execution is stuck-> +" + " + exeblobal." + exeblobal. 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 {/* 작업 대기열이 비어 있으면 새로운 작업이 새로운 작업이 결합되어 깨어날 때까지 기다리고 있습니다. }} catch (InterruptedException IE) {log.error (예 :); }}/* 실행 작업을 수행하십시오*/if (runing) {currentthread.lastcommand = null; currentthread.lastcommand = taskqueue.poll; } if (currentthread.lastcommand! = null) {if (currentthread.lastcommand.iscancel) {// 작업이 취소 된 경우 계속; }/* 작업을 실행하십시오* ///setsubmittimel; currentthread.lastExecuteTime = System.CurrentTimEmillis; {currentthread.lastcommand.run;} catch (Exception e) {log.error ( "worker <" " + currentShread.getName +" "> execute <" + currentShread.last.get.get.get.get.get.get.get.get.get.get.get.get. 오류가 발생했습니다. ", e); } long timel1 = System.CurrentTimeMillis- currentthread.lastExecuteTime; if (timel1 <= 20) {} else if (timel1 <= 100l) {log.info ( "worker <" " + currentthread.getname +" "> 작업을 완료했습니다 :" + currentthread.lastcommand.tostring + "execution time :" + timel1); currentthread.getname + ""> 작업 완료의 장기 실행 : " + currentthread.lastcommand.toString +" ""작업 스크립트 로직 시간 소비 : " + timel1);} else {log.info ("worker < " + currentShread.getname +" "> 오랜 시간 동안 작업의 실행 완료. + ""삭제되어야하는지 고려하십시오 "작업 스크립트 시간 소요 :" + TIMEL1); } currentthread.lastExecuteTime = 0; }} log.error ( "스레드 엔드, 작업자 <" " + 스레드 .currentThread.getName +" "> exit"); } / *** 사용자 정의 스레드* / public class mythread는 스레드를 확장합니다. { / **** @param tid 사용자 정의 스레드 ID* @param run 실행 방법* @param 이름 스레드 이름* / public mythread (long tid, threadgroup group, runble run) {super (group, run, name); this._id = tid; } // 스레드의 사용자 정의 ID public long _id; // 실행 작업 공개 휘발성 Taskevent LastCommand; // 작업 실행을 시작하는 시간 공개 휘발성 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 running; } @override public String toString {return "stread {" + "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 스레드; if (runnable == null) {thread = new Mythread (tid, group, this, name + "-" + tid + "-" + i);} else {thread = new mythread (tid, group, runnable, name + "-" + tid + "; } stread.start; threads.add (스레드); } this.name = 이름; }볼 수 있듯이 여기서 나는 신화 스레드 클래스를 선언합니다.
왜 이것에 대해 생각합니까? 예를 들어, 공유 데이터가없고 스레드 임계 영역 처리 흐름과 같은 로그 쓰기 데이터를 처리하는 경우 N 스레드를 사용하여 그러한 작업을 처리하는 것을 고려할 수 있습니다. 더러운 데이터를 생성하지 않습니다.
팀을 구성하고 기술 캐스팅을 요청하려면 단일 대기열을 처리해야합니다. ThreadModel에는 신화가 하나만 있어야합니다. 이는 더 이상 잠금에 의존하지 않는 데이터 및 스레드 임계 영역을 공유하는 문제를 해결하기 위해 차단 모드 직렬 실행 (또는 대기열 실행)으로 간주되지 않습니다.
나는 매우 못 생겼다. 용서 해주세요
위의 그림과 같이, 각 스레드 모델에는 두 개의 대기열, 하나의 timetaskevent 및 다른 taskvent가 있으며, 전역 타이머 스레드가있을 것입니다.
글로벌 타이머 스레드의 기능은 스레드 모델의 TimetAskevent를 처리하고 찾아야하므로 Taskvent 팀에 추가됩니다. 최종 실행은 Taskvent 대기열입니다
TimetAskevent가 해당 스레드 모델에 저장 해야하는 이유는 무엇입니까? 예를 들어, 스레드 A (ThreadModel 인스턴스)가 일정 시간 동안 실행되면 리소스를 닫고 자유롭게해야하므로 해당 시간표를 찾아 제거하려면 다른 장소로 가야합니다.
Package Net.sz.engine.thread; import java.util.hashmap; import java.util.map;/** * <br> * 저자 떨어지는 프로그래머 <br> * 메일 [email protected] <br> * 전화 13882122019 <br> */class stread Extrends Thread extrends Thread velected restrend extrense public timerthread {super (strookpool.globlthreadgroup, "Global Timer Thread"); } @override public void run {while (true) {synchronized (syn_object) {try {syn_object.wait (2);} catch (interpruptedExcept ex) {}} hashmap <long, threadModel> hashmap = new hashmap <> (threadpool.getThreadMap); hashmap.entryset) {long key = entryset.getkey; threadModel value = rettrentset.getValue; 가치. 타임 메란; }}}}
스레드 모델 관리자
패키지 net.sz.engine.thread; import java.util.hashmap; import java.util.concurrent.concurrenthashmap; import net.sz.engine.script.manager.scriptmanager; import net.sz.engine.globtimerevent; import net.sz.engine.timer.timer. org.apache.log4j.logger;/** * 스레드 관리자 * * <br> * 저자 실패 프로그래머 <br> * 메일 [email protected] <br> * 전화 13882122019 <br> */public class threadpool {정적 개인 최종 로그 = logger.getlogger (threadpool.class); 정적 공개 최종 Long Globlthread; 정적 개인 최종 TIMERTHHEDGLOBLTIMERTHREAD; 정적 최종 Long CheckThreadTimerThreadModel; 정적 공개 Final ThreadGroup GloblthreadGroup = New ThreadGroup ( "Global ThreadGroup"); 정적 공개 Final ThreadGroup Unknownthreadgroup = New ThreadGroup (GloBlthreadGroup, "Unknown ThreadGroup"); 정적 개인 최종 ConcurrEthashMap <Long, ThreadModel> ThreadMap = New ConcurrenThashMap <>; public static void main (string [] args) {threadpool.addtimertask (globlthread, new Timertaskevent (1000) {@overridepublic void run {log.error ( "ssss");}}); } static {// 글로벌 스레드 생성 globlthread = addThreadModel (globlthreadgroup, "globlthread"); // 지정된 작업 타이밍을 실행하여 풋 스텝 ADDTIMERTASK (GloBlthread, New GlobtimerEvent (scriptManager.getInstance.getBaseScriptEntry)); // 서버 소비 타이밍 모델 AddTimerTask (GloBlthread, New PrintLnServerMemoryTimerEvent) 쿼리; // 타이머 스레드 작성 globltimerthread = new Timerthread; globltimerthread.start; // 스레드를 확인한 check checkThreadTimerThreadModel = addThreadModel (globlthreadgroup, "strooktimer event"); AddTimerTask (CheckThreadTimerThreadModel, New CheckthreadTimerEvent); } / ** * 지정된 ID 스레드 모델을 삭제할 때 상태를 정지 상태로 설정 * * @param tid * @return * / static public stridemodel 제거 (long tid) {ThreadModel remove = threadmap.remove (tid); if (remove! = null) {remove.stop; } 반환 제거; } / ** * 스레드 풀에서 모든 스레드를 가져옵니다 * * @return * / 정적 공개 consurethashMap <long, ThreadModel> getThreadMap {return ThreadMap; } / ** * 스레드 풀에서 스레드를 가져옵니다 * * @param threadid * @return * / static public threadmodel getThreadModel (long ThreadId) {ThreadModel get = rooidmmap.get (ordreadId); if (get == null) {log.error ( "스레드 모델을 찾을 수 없습니다 :" + threadId, new Exception ( "스레드 모델을 찾을 수 없습니다 :" + threadid); } return get; } / ** * 스레드 풀에 스레드를 등록 * <br> * 기본 그룹화 unknownthreadgroup * * @param name 스레드 이름 * @return * / static public long addthreadmodel (문자열 이름) {return addThreadModel (unclythreadgroup, name); } / ** * 스레드 풀에 스레드를 등록 * <br> * 기본 그룹화 unknownthreadgroup * * @param name strookname * @param strandcount strandCount * / static public long addThreadModel (문자열 이름, introokcount) {return addThreadModel (unknoythreadgroup, name, stroomcount); } / *** 스레드 풀에 스레드를 등록** @param 그룹 스레드 그룹화 정보* @param 이름 스레드 이름* @return* / static public long addthreadmodel (ThreadGroup Group, String Name) {return addThreadModel (그룹, 이름, 1); } / *** 스레드 풀에 스레드를 등록** @param 그룹 스레드 그룹화 정보* @param name strookname* @param strookcount strookcount* @return* / static public long addthreadmodel (스레드 그룹 그룹, 문자열 이름, int 스레드 카운트) {return addthreadmodel (그룹, 이름, null, threadCount); } / *** 스레드 풀에 스레드를 등록** @param Group ThreadGroup 정보* @param name runname* @param runnable* @param strookcount strookcount* / stroom public long addthreadmodel (스레드 그룹 그룹, 문자열 이름, runnable runnable, int stresscount) {strood model threadmodel (Group, name, rundremmodel); let } / ** * 스레드 풀에 스레드를 등록 * * @Param ThreadModel * / static public long addThreadModel (ThreadModel ThreadModel) {ThreadMap.put (ThreadModel.getId, ThreadModel); retud ThreadModel.getID; } / ** * 태스크 추가 * * @param threadId * @param task * @return * / 정적 공개 부울 addtask (long readid, taskevent task) {ThreadModel threadModel = getThreadModel (threadId); if (ThreadModel! = null) {ThreadModel.AddTask (task); true를 반환합니다. } false를 반환합니다. } / ** * 타이머 작업 추가 * * @param threadid * @param task * / static public boolean addtimertask (Long ThreadId, TimertAskevent task) {ThreadModel ThreadModel = getThreadModel (threadId); if (ThreadModel! = null) {ThreadModel.AddTimer (task); true를 반환합니다. } false를 반환합니다. } / ** * 작업 추가, 현재 스레드에 작업 추가 * * @param task * / static public boolean addcurrentthreadtask (taskevent task) {스레드 currentthread = thread.currentthread; if (strookmodel.mythread의 currentthread 인스턴스) {long readid = currentthread.getId; threadModel roodmodel = getThreadModel (threadId); if (ThreadModel! = null) {ThreadModel.AddTask (task); true; }} 거짓을 반환합니다. } / ** * 타이머 작업을 추가하고 현재 스레드에 작업을 추가하십시오 * @param task * @return * / 정적 공개 부울 AddCurrentThreadtimertask (TimertAskevent task) {스레드 currentShread = thread.currentThread; if (strookmodel.mythread의 currentthread 인스턴스) {long readid = currentthread.getId; threadModel roodmodel = getThreadModel (threadId); if (ThreadModel! = null) {ThreadModel.AddTimer (task); true; }} 거짓을 반환합니다. }}
다음으로, 사용법을 살펴 보겠습니다
이전 기사의 스레드 소개 코드
public static void main (string [] args)은 중단 exception {// 스레드 병렬 처리, 여러 스레드는 여러 작업/함수를 실행합니다. 새 스레드 (New Run2) .Start; } // task1 정적 클래스 run1은 runnable {@override public void run {// 실행 작업 1 run1; // task 3 run3; }} // task2 static class run2 implements runnable {@override public void run {// execute task 3 run3; // execute task 1 run1; // task 2 run2; }} // 작업 1 public static void run1 {System.out.println ( "run1->" + System.CurrentTimeMillis); } // 작업 2 public static void run2 {System.out.println ( "run2->" + System.CurrentTimeMillis); } // task 3 public static void run3 {system.out.println ( "run3->" + System.CurrentTimeMillis); }코드를 모드로 전환했습니다
public static void main (string [] args) 던지기 인터럽트 exception {// 스레드는 평행하고 여러 스레드는 여러 작업/함수 long test1 = threadpool.addThreadModel ( "Test Thread-1")을 실행합니다. long test2 = threadpool.addthreadmodel ( "Test Thread-2"); // task add threadpool.addtask (test1, new run1); ThreadPool.addtask (Test2, New Run2); // 타이머 작업을 추가 threadPool.AddTimerTask (Test1, New TimerRun1); ThreadPool.addtimertask (Test2, New Timerrun2); } // task1 static class run1은 taskevent {@override public void run {// execute task 1 run1; // task 3 run3; }} // task1 정적 클래스 Timerrun1은 TimerTasKevent를 확장합니다. {public timerrun1 {super (500); // 500ms 무제한 실행} @override public void run {// execute task 1 run1; // task 3 run3; }} // task2 static class run2는 taskevent {@override public void run {// execute task 3 run3; // execute task 1 run1; // task 2 run2; }} // task2 static class timerrun2는 TimerTasKevent를 확장합니다. {public timerrun2 {super (500); // 500ms 무제한 실행} @override public void run {// execute task 3 run3; // task 1 run1; // task 2 run2; }} // task1 public static void run1 {system.out.println ( "run1->" + System.CurrentTimeMillis); } // task2 public static void run2 {system.out.println ( "run2->" + System.CurrentTimeMillis); } // task 3 public static void run3 {system.out.println ( "run3->" + System.CurrentTimeMillis); }다음으로 실행 효과를 살펴 보겠습니다
RUN1-> 1472120543013RUN3-> 1472120543013RUN3-> 1472120543017RUN1-> 1472120543017RUN2-> 14721205 43017RUN1-> 1472120543517RUN3-> 1472120543517RUN2-> 1472120543517RUN1-> 1472120544018RUN3-> 1477 2120544018RUN2-> 1472120544018RUN1-> 1472120544520RUN3-> 1472120544520RUN2-> 147212054520RUN1 -> 1472120545021RUN3-> 1472120545021RUN2-> 1472120545021RUN1-> 14721205455521RUN3-> 14721205455521
모든 것이 정상입니다.
이것은 내 커스텀 스레딩 모델입니다.
이 시점에서 내 사용자 지정 스레딩 모델이 완료되었습니다.
그렇다면 장점과 단점은 무엇입니까?
장점은 현재 실행 상황을 포함하여 데이터 흐름 제어가 매우 명확하다는 것입니다.
단점,이 사용자 지정 스레드 모델은 여전히 스레드 데이터 보안 및 임계 영역의 문제를 해결할 수 없으며 적절한 시간에 잠금 또는 기타 양식으로 여전히 해결해야합니다.
나는 위대한 신들이 단점을 지적하기를 바랍니다. 그래서 나는 그들을 즉시 수정할 수 있습니다.