当前位置:首页 » 编程语言 » 线程调度java

线程调度java

发布时间: 2024-10-31 06:31:53

java的多线程与linux的多线程的关系

java自己实现了线程库,也就是说java的线程并不和操作系统的线程对应,jvm在操作系统上面是一个进程,当这个进程被操作系统调度到后,jvm内部实现的线程库再调度java线程,为什么是这样呢?考虑到以前的操作系统内核,比如linux,在以前都不直接支持线程,用户线程和内核线程是多对一的关系,solaris一度也是这样,所以java当然心有余而力不足了,你操作系统都不能完美支持线程,你让我实现不是难为我吗?在那个年代,java多线程的调度完全是自主的,操作系统根本不知道java是多线程的,调度策略完全自己实现,单cpu下肯定是分时的,多cpu下就看jvm会不会建立多cpu上的多jvm实例了。
到了后来,操作系统内核纷纷都支持了多线程(windows开始就支持),那么java也要考虑推卸一些责任了,这样java线程就和操作系统线程一一对应或多多对应了,这个时候,如果是一一对应,那么线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个Thread.run就会调用一个fork产生一个线程。
问:java获得cup使用权采用的抢占机制,使用cup的时候是分时机制,这句话对不对?
答:部分对,早期实现,基本可以实现抢占式,但是现代实现,如果系统不支持抢占,那么jvm也无所谓抢占了。
问:多线程使用cup和使用的操作系统有关还是java机制有关(xp是什么机制)
答:早期是java机制实现,现在大部分是操作系统实现的,java机制仅仅保留了相关策略从而影响调度;xp是基于优先级的抢占式调度,其性能很大程度依赖于动态优先级提升

㈡ java线程池之ScheledThreadPoolExecutor实现原理

java中异步周期任务调度有Timer,ScheledThreadPoolExecutor等实现,目前单机版的定时调度都是使用ScheledThreadPoolExecutor去实现,那么它是如何实现周期执行任务的呢?其实它还是利用ThreadPoolExecutor线程池去执行任务,这一点从它是继承自ThreadPoolExecutor救可以看的出来,其实关键在于如何实现任务的周期性调度,

ScheledThreadPoolExecutor类以及核心函数

首先ScheledThreadPoolExecutor是实现ScheledExecutorService接口,它主要定义了四个方法:

周期调度一个Runnable的对象

周期调度一个Callable的对象

固定周期调度Runnable对象 (不管上一次Runnable执行结束的时间,总是以固定延迟时间执行 即 上一个Runnable执行开始时候 + 延时时间 = 下一个Runnable执行的时间点)

以固定延迟调度unnable对象(当上一个Runnable执行结束后+固定延迟 = 下一个Runnable执行的时间点)

{publicScheledFuture<?>schele(Runnablecommand,longdelay,TimeUnitunit);public<V>ScheledFuture<V>schele(Callable<V>callable,longdelay,TimeUnitunit);publicScheledFuture<?>scheleAtFixedRate(Runnablecommand,longinitialDelay,longperiod,TimeUnitunit);publicScheledFuture<?>scheleWithFixedDelay(Runnablecommand,longinitialDelay,longdelay,TimeUnitunit);}

其次,ScheledThreadPoolExecutor是继承ThreadPoolExecutor,所以它是借助线程池的能力去执行任务,然后自身去实现周期性调度。从构造方法调用父类的线程池的构造方法,核心线程数是构造方法传入,这里可以看到最大线程数是Integer的最大值即2147483647, 还有等待队列是DelayedWorkQueue,它是实现延时的关键.

/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}

scheleAtFixedRate是实现周期性调度的方法,调度任务就是实现Runnable对象, 以及系统的开始延时时间,周期的调度的间隔时间。

计算初始触发时间和执行周期,并和传入的Runnable对象作为参数封装成 ScheledFutureTask,然后调用decorateTask装饰Tas(默认实现为空)。

设置ScheledFutureTask对象outerTask为t(默认就是它自己)。

调用delayedExecute延迟执行任务。

publicScheledFuture<?>scheleAtFixedRate(Runnablecommand,longinitialDelay,longperiod,**TimeUnitunit){if(command==null||unit==null)thrownewNullPointerException();if(period<=0)();ScheledFutureTask<Void>sft=newScheledFutureTask<Void>(command,null,triggerTime(initialDelay,unit),unit.toNanos(period));RunnableScheledFuture<Void>t=decorateTask(command,sft);sft.outerTask=t;delayedExecute(t);returnt;}

判断线程池状态,如果不是处于running状态,则拒绝该任务。

将该任务加入父类的延迟队列(实际为初始化的DelayedWorkQueue对象)

再次判断线程池不是处于running状态,并且,判断是否是处于shutdown状态并且标志是否是true(默认是false,表示是否线程次处于shutdown状态下是否继续执行周期性任务),若果为true,则从队列删除任务,false,则确保启动线程来执行周期性任务

privatevoiddelayedExecute(RunnableScheledFuture<?>task){if(isShutdown())reject(task);else{super.getQueue().add(task);if(isShutdown()&&!canRunInCurrentRunState(task.isPeriodic())&&remove(task))task.cancel(false);elseensurePrestart();}}

获取线程池数量

如果小于核心线程数,则启动核心线程执行任务,如果线程数为空,则启动非核心线程

voidensurePrestart(){intwc=workerCountOf(ctl.get());if(wc<corePoolSize)addWorker(null,true);elseif(wc==0)addWorker(null,false);}ScheledFutureTask的run函数

获取是否是周期性任务

判断是否线程池状态是否可以执行任务,如果为true,则取消任务 3 如果是非周期性任务,则直接调用父类FutureTask的run方法, 4 如果是周期性任务,则调用FutureTask的runAndReset函数, 如果该函数返回为true,则调用setNextRunTime设置下一次运行的时间, 并且还行reExecutePeriodic再次执行周期性任务。

publicvoidrun(){booleanperiodic=isPeriodic();if(!canRunInCurrentRunState(periodic))cancel(false);elseif(!periodic)ScheledFutureTask.super.run();elseif(ScheledFutureTask.super.runAndReset()){setNextRunTime();reExecutePeriodic(outerTask);}}

判断线程池是否处于可执行任务的状态,如果为true,则重新将设置下一次运行时间的任务加入父类的等待队列,

如果线程池处于不可运行任务的状态,则并且从等待队列中移除成功, 调用任务的取消操作,否则调用ensurePrestart确保启动线程执行任务

voidreExecutePeriodic(RunnableScheledFuture<?>task){if(canRunInCurrentRunState(true)){super.getQueue().add(task);if(!canRunInCurrentRunState(true)&&remove(task))task.cancel(false);elseensurePrestart();}}DelayedWorkQueue类核心函数

DelayedWorkQueue是继承AbstractQueue,并实现BlockingQueue接口

<Runnable>implementsBlockingQueue<Runnable>{

核心字段

//初始容量为_CAPACITY=16;//等待队列,只能保存RunnableScheledFuture对象privateRunnableScheledFuture<?>[]queue=newRunnableScheledFuture<?>[INITIAL_CAPACITY];//锁privatefinalReentrantLocklock=newReentrantLock();//对俄大小privateintsize=0;//leader线程,表示最近需要执行的任务的线程。privateThreadleader=null;//条件锁=lock.newCondition();

offer函数:

将添加的参数转换成RunnableScheledFuture对象。

加全局锁。

获取当前队列的size,如果等于队列的长度,则嗲用grow扩容,增加50%的数组长度。

size加1。

如果数组为0,则将加入的对象放在索引为0的位置,然后设置ScheledFutureTask的heapIndex的索引(便于后续快速删除)。

调用siftUp做堆的上浮操作,这里是小根堆的操作。

如果队列中第一个元素是传入的对象,则将laader设置null

释放锁

返回true

publicbooleanoffer(Runnablex){if(x==null)thrownewNullPointerException();RunnableScheledFuture<?>e=(RunnableScheledFuture<?>)x;finalReentrantLocklock=this.lock;lock.lock();try{inti=size;if(i>=queue.length)grow();size=i+1;if(i==0){queue[0]=e;setIndex(e,0);}else{siftUp(i,e);}if(queue[0]==e){leader=null;available.signal();}}finally{lock.unlock();}returntrue;}

siftUp主要就是做小根堆的上移操作,从if (key.compareTo(e) >= 0) 看出,如果key大于parent索引的元素,则停止。

/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}0

poll函数

加锁

获取队列中索引为0的云元素,若果为null或者第一个元素的执行时间戳时间大于当前时间则直接返回null,否则调用finishPoll将第一个元素返回.

释放锁

/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}1

将队列size 减 1

获取队列中队列中最后一个元素,并且设置队列最后一个为null

最后一个元素不为null,则调用sfitdown进行,将最后一个元素设置到索引为0的位置,将下移操作,重新调整小根堆。

ScheledFutureTask的heapIndex为-1

/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}2ScheledFutureTask的compareTo函数

ScheledFutureTask实现compareTo方法逻辑

首先比较是否是同一个对象

若果是ScheledFutureTask对象,则比较time的大小,time是下一次执行的任务的时间戳,如果不是,则比较 getDelay的时间大小

/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}3

ScheledThreadPoolExecutor的take函数就是ThreadPoolExecutor的从任务队列中获取任务,没有任务则一直等待(这里是线程数小于核心线程数的情况)

加可中断锁

获取队列中第一个元素的任务,从前面可以知道此任务执行的时间戳最小的任务

如果第一个任务为空,则再全局的锁的条件锁上等待,

如果第一个任务不为空,则获取延迟时间,如果延时时间小于0,说明第一个任务已经到时间了,则返回第一个任务。

如果leader线程不为空,则让线程在全局锁的条件锁上等待

如果leader为空,则将获取第一个任务的当前线程赋值为leader变量。

在全局锁的条件锁上等待delay纳秒, 等待结束后,如果当前线程还是等于leader线程,则重置leader为空

最后判断 leader为空并且第一个任务不为空,则唤醒全局锁上条件锁的等待的线程。

释放全局锁。

/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}4

总结 综合前面所述,线程池从DelayedWorkQueue每次取出的任务就是延迟时间最小的任务, 若果到达时间的任务,则执行任务,否则则用条件锁Conditon的wait进行等待,执行完后,则用signal进行唤醒下一个任务的执行。

㈢ Java线程的知识要点

一、进程的概念

进程表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自拦念己的程序,系统就创建一个进程,并给它分配资源,包括内存空间、磁盘空间、I/O设备等。然后,把该进程放入就绪队列。进程调度程序选中它,为它分配CPU以及其他有关的资源,该进程才真正运行。简伍困所以,北京电脑培训发现进程是系统中的并发执行的单位。

二、线程的概念

线程:(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

三、引用线程的优势

(1)易于调度。

(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分或相同部分。

(3)开销少。创建线程比创建进程要快,所需开销很少。

(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。

四、进程与线程的关系

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)处理机分给线程,即真正在处理机上运行橘悉的是线程。

(4)线程在执行过程中,要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

简单来说:

1、一个程序至少有一个进程,一个进程至少有一个线程。

2、进程在执行过程中拥有独立的资源,而多个线程共享进程中的资源。


㈣ 鑳借В閲娄竴涓媕ava镄勭嚎绋嬬殑浣跨敤

闅忕潃璁$畻链虹殑椋为熷彂灞曪纴涓浜鸿$畻链轰笂镄勬搷浣灭郴缁熶篃绾风悍閲囩敤澶氢换锷″拰鍒嗘椂璁捐★纴灏嗘棭链熷彧链夊ぇ鍨嬭$畻链烘墠鍏锋湁镄勭郴缁熺壒镐у甫鍒颁简涓浜鸿$畻链虹郴缁熶腑銆备竴鑸鍙浠ュ湪钖屼竴镞堕棿鍐呮墽琛屽氢釜绋嫔簭镄勬搷浣灭郴缁熼兘链夎繘绋嬬殑姒傚康銆备竴涓杩涚▼灏辨槸涓涓镓ц屼腑镄勭▼搴忥纴钥屾疮涓涓杩涚▼閮芥湁镊宸辩嫭绔嬬殑涓鍧楀唴瀛樼┖闂淬佷竴缁勭郴缁熻祫婧愩傚湪杩涚▼姒傚康涓锛屾疮涓涓杩涚▼镄勫唴閮ㄦ暟鎹鍜岀姸镐侀兘鏄瀹屽叏镫绔嬬殑銆侸ava绋嫔簭阃氲繃娴佹带鍒舵潵镓ц岀▼搴忔祦锛岀▼搴忎腑鍗曚釜椤哄簭镄勬祦鎺у埗绉颁负绾跨▼锛屽氱嚎绋嫔垯鎸囩殑鏄鍦ㄥ崟涓绋嫔簭涓鍙浠ュ悓镞惰繍琛屽氢釜涓嶅悓镄勭嚎绋嬶纴镓ц屼笉钖岀殑浠诲姟銆傚氱嚎绋嬫剰锻崇潃涓涓绋嫔簭镄勫氲岃鍙ュ彲浠ョ湅涓婂幓鍑犱箮鍦ㄥ悓涓镞堕棿鍐呭悓镞惰繍琛屻

绾跨▼涓庤繘绋嬬浉浼硷纴鏄涓娈靛畬鎴愭煇涓鐗瑰畾锷熻兘镄勪唬镰侊纴鏄绋嫔簭涓鍗曚釜椤哄簭镄勬祦鎺у埗锛涗絾涓庤繘绋嬩笉钖岀殑鏄锛屽悓绫荤殑澶氢釜绾跨▼鏄鍏变韩涓鍧楀唴瀛樼┖闂村拰涓缁勭郴缁熻祫婧愶纴钥岀嚎绋嬫湰韬镄勬暟鎹阃氩父鍙链夊井澶勭悊鍣ㄧ殑瀵勫瓨鍣ㄦ暟鎹锛屼互鍙娄竴涓渚涚▼搴忔墽琛屾椂浣跨敤镄勫爢镙堛傛墍浠ョ郴缁熷湪浜х敓涓涓绾跨▼锛屾垨钥呭湪钖勪釜绾跨▼涔嬮棿鍒囨崲镞讹纴璐熸媴瑕佹瘆杩涚▼灏忕殑澶氾纴姝e洜濡傛わ纴绾跨▼琚绉颁负杞昏礋钻疯繘绋嬶纸light-weight process锛夈备竴涓杩涚▼涓鍙浠ュ寘钖澶氢釜绾跨▼銆

涓涓绾跨▼鏄涓涓绋嫔簭鍐呴儴镄勯‘搴忔带鍒舵祦銆
1. 杩涚▼锛氭疮涓杩涚▼閮芥湁镫绔嬬殑浠g爜鍜屾暟鎹绌洪棿锛堣繘绋嬩笂涓嬫枃锛 锛岃繘绋嫔垏鎹㈢殑寮阌澶с
2. 绾跨▼锛氲交閲忕殑杩涚▼锛屽悓涓绫荤嚎绋嫔叡浜浠g爜鍜屾暟鎹绌洪棿锛屾疮涓绾跨▼链夌嫭绔嬬殑杩愯屾爤鍜岀▼搴忚℃暟鍣锛圥C锛夛纴绾跨▼鍒囨崲镄勫紑阌灏忋
3. 澶氲繘绋嬶细鍦ㄦ搷浣灭郴缁熶腑锛岃兘钖屾椂杩愯屽氢釜浠诲姟绋嫔簭銆
4. 澶氱嚎绋嬶细鍦ㄥ悓涓搴旂敤绋嫔簭涓锛屾湁澶氢釜椤哄簭娴佸悓镞舵墽琛屻

6锛1锛1 绾跨▼镄勬傚康妯″瀷

Java鍐呭湪鏀鎸佸氱嚎绋嬶纴瀹幂殑镓链夌被閮芥槸鍦ㄥ氱嚎绋嬩笅瀹氢箟镄勶纴Java鍒╃敤澶氱嚎绋嬩娇鏁翠釜绯荤粺鎴愪负寮傛ョ郴缁熴侸ava涓镄勭嚎绋嬬敱涓夐儴鍒嗙粍鎴愶纴濡傚浘6.1镓绀恒

1. 铏氭嫙镄凛PU锛屽皝瑁呭湪Java.lang.Thread绫讳腑銆
2. CPU镓镓ц岀殑浠g爜锛屼紶阃掔粰Thread绫汇
3. CPU镓澶勭悊镄勬暟鎹锛屼紶阃掔粰Thread绫汇

锲6.1绾跨▼

6. 1. 2 绾跨▼浣(1)

Java镄勭嚎绋嬫槸阃氲繃Java.lang.Thread绫绘潵瀹炵幇镄勚傚綋鎴戜滑鐢熸垚涓涓猅hread绫荤殑瀵硅薄涔嫔悗,涓涓鏂扮殑绾跨▼灏变骇鐢熶简銆

姝ょ嚎绋嫔疄渚嬭〃绀筼ava瑙i喷鍣ㄤ腑镄勭湡姝g殑绾跨▼锛岄氲繃瀹冨彲浠ュ惎锷ㄧ嚎绋嬨佺粓姝㈢嚎绋嬨佺嚎绋嬫寕璧风瓑锛屾疮涓绾跨▼閮芥槸阃氲繃绫籘hread鍦↗ava镄勮蒋浠跺寘Java.lang涓瀹氢箟锛屽畠镄勬瀯阃犳柟娉曚负锛

public Thread 锛圱hreadGroup group锛孯unnable target锛孲tring name锛夛绂

鍏朵腑锛実roup 鎸囨槑璇ョ嚎绋嬫墍灞炵殑绾跨▼缁勶绂target瀹为檯镓ц岀嚎绋嬩綋镄勭洰镙囧硅薄锛屽畠蹇呴’瀹炵幇鎺ュ彛Runnable锛 name涓虹嚎绋嫔悕銆侸ava涓镄勬疮涓绾跨▼閮芥湁镊宸辩殑钖岖О锛孞ava鎻愪緵浜嗕笉钖孴hread绫绘瀯阃犲櫒锛屽厑璁哥粰绾跨▼鎸囧畾钖岖О銆傚傛灉name涓簄ull镞讹纴鍒橨ava镊锷ㄦ彁渚涘敮涓镄勫悕绉般
褰扑笂杩版瀯阃犳柟娉旷殑镆愪釜鍙傛暟涓簄ull镞讹纴鎴戜滑鍙寰楀埌涓嬮溃镄勫嚑涓鏋勯犳柟娉曪细

public Thread 锛堬级锛
public Thread 锛圧unnable target锛夛绂
public Thread 锛圧unnable target锛孲tring name锛夛绂
public Thread 锛圫tring name锛夛绂
public Thread 锛圱hreadGroup group锛孯unnable target锛夛绂
public Thread 锛圱hreadGroup group锛孲tring name锛夛绂

涓涓绫诲0鏄庡疄鐜癛unnable鎺ュ彛灏卞彲浠ュ厖褰撶嚎绋嬩綋锛屽湪鎺ュ彛Runnable涓鍙瀹氢箟浜嗕竴涓鏂规硶 run锛堬级锛
public void run锛堬级锛

浠讳綍瀹炵幇鎺ュ彛Runnable镄勫硅薄閮藉彲浠ヤ綔涓轰竴涓绾跨▼镄勭洰镙囧硅薄锛岀被Thread链韬涔熷疄鐜颁简鎺ュ彛Runnable锛屽洜姝ゆ垜浠鍙浠ラ氲繃涓ょ嶆柟娉曞疄鐜扮嚎绋嬩綋銆

锛堜竴锛夊畾涔変竴涓绾跨▼绫伙纴瀹幂户镓跨嚎绋嬬被Thread骞堕吨鍐椤叾涓镄勬柟娉 run锛堬级锛岃繖镞跺湪鍒濆嫔寲杩欎釜绫荤殑瀹炰緥镞讹纴鐩镙噒arget鍙涓簄ull锛岃〃绀虹敱杩欎釜瀹炰緥瀵规潵镓ц岀嚎绋嬩綋銆傜敱浜嶫ava鍙鏀鎸佸崟閲岖户镓匡纴鐢ㄨ繖绉嶆柟娉曞畾涔夌殑绫讳笉鑳藉啀缁ф圹鍏跺畠鐖剁被銆

锛堜簩锛夋彁渚涗竴涓瀹炵幇鎺ュ彛Runnable镄勭被浣滀负涓涓绾跨▼镄勭洰镙囧硅薄锛屽湪鍒濆嫔寲涓涓猅hread绫绘垨钥匮hread瀛愮被镄勭嚎绋嫔硅薄镞讹纴鎶婄洰镙囧硅薄浼犻掔粰杩欎釜绾跨▼瀹炰緥锛岀敱璇ョ洰镙囧硅薄鎻愪緵绾跨▼浣 run锛堬级銆傝繖镞讹纴瀹炵幇鎺ュ彛Runnable镄勭被浠岖劧鍙浠ョ户镓垮叾瀹幂埗绫汇

姣忎釜绾跨▼閮芥槸阃氲繃镆愪釜鐗瑰畾Thread瀵硅薄镄勬柟娉时un( )𨱒ュ畬鎴愬叾镎崭綔镄勶纴鏂规硶run( )绉颁负绾跨▼浣撱傚浘6.2琛ㄧず浜呙ava绾跨▼镄勪笉钖岀姸镐佷互鍙婄姸镐佷箣闂磋浆鎹㈡墍璋幂敤镄勬柟娉曘

锲6.2 绾跨▼镄勭姸镐

1. 鍒涘缓鐘舵(new Thread)
镓ц屼笅鍒楄鍙ユ椂锛岀嚎绋嫔氨澶勪簬鍒涘缓鐘舵侊细
Thread myThread = new MyThreadClass( );
褰扑竴涓绾跨▼澶勪簬鍒涘缓鐘舵佹椂锛屽畠浠呬粎鏄涓涓绌虹殑绾跨▼瀵硅薄锛岀郴缁熶笉涓哄畠鍒嗛厤璧勬簮銆

2. 鍙杩愯岀姸镐( Runnable )
Thread myThread = new MyThreadClass( );
myThread.start( );
褰扑竴涓绾跨▼澶勪簬鍙杩愯岀姸镐佹椂锛岀郴缁熶负杩欎釜绾跨▼鍒嗛厤浜嗗畠闇镄勭郴缁熻祫婧愶纴瀹夋帓鍏惰繍琛屽苟璋幂敤绾跨▼杩愯屾柟娉曪纴杩欐牱灏变娇寰楄ョ嚎绋嫔勪簬鍙杩愯( Runnable )鐘舵併傞渶瑕佹敞镒忕殑鏄杩欎竴鐘舵佸苟涓嶆槸杩愯屼腑鐘舵侊纸Running )锛屽洜涓虹嚎绋嬩篃璁稿疄闄呬笂骞舵湭鐪熸h繍琛屻傜敱浜庡緢澶氲$畻链洪兘鏄鍗曞勭悊鍣ㄧ殑锛屾墍浠ヨ佸湪钖屼竴镞跺埢杩愯屾墍链夌殑澶勪簬鍙杩愯岀姸镐佺殑绾跨▼鏄涓嶅彲鑳界殑锛孞ava镄勮繍琛岀郴缁熷繀椤诲疄鐜拌皟搴︽潵淇濊瘉杩欎簺绾跨▼鍏变韩澶勭悊鍣ㄣ

3. 涓嶅彲杩愯岀姸镐侊纸Not Runnable锛
杩涘叆涓嶅彲杩愯岀姸镐佺殑铡熷洜链夊备笅鍑犳浔锛
1) 璋幂敤浜唖leep锛堬级鏂规硶;
2) 璋幂敤浜唖uspend锛堬级鏂规硶;
3) 涓虹瓑鍊欎竴涓𨱒′欢鍙橀噺锛岀嚎绋嬭皟鐢╳ait锛堬级鏂规硶;
4) 杈揿叆杈揿嚭娴佷腑鍙戠敓绾跨▼阒诲;
涓嶅彲杩愯岀姸镐佷篃绉颁负阒诲炵姸镐侊纸Blocked锛夈傚洜涓烘煇绉嶅师锲狅纸杈揿叆/杈揿嚭銆佺瓑寰呮秷鎭鎴栧叾瀹冮樆濉炴儏鍐碉级锛岀郴缁熶笉鑳芥墽琛岀嚎绋嬬殑鐘舵併傝繖镞跺嵆浣垮勭悊鍣ㄧ┖闂诧纴涔熶笉鑳芥墽琛岃ョ嚎绋嬨

4. 姝讳骸鐘舵侊纸Dead锛
绾跨▼镄勭粓姝涓鑸鍙阃氲繃涓ょ嶆柟娉曞疄鐜帮细镊铹舵挙娑堬纸绾跨▼镓ц屽畬锛夋垨鏄琚锅沧锛堣皟鐢╯top()鏂规硶锛夈傜洰鍓崭笉鎺ㄨ崘阃氲繃璋幂敤stop()𨱒ョ粓姝㈢嚎绋嬬殑镓ц岋纴钥屾槸璁╃嚎绋嬫墽琛屽畬銆

http://www.bc-cn.net/Article/kfyy/java/jc/200410/83.html

热点内容
怎么样解压qq文件 发布:2024-10-31 08:58:46 浏览:74
安卓国际服怎么加模组 发布:2024-10-31 08:47:40 浏览:670
天翼高清盒子怎么配置 发布:2024-10-31 08:41:42 浏览:924
建材直播脚本 发布:2024-10-31 08:34:26 浏览:241
数据库备份表 发布:2024-10-31 08:32:26 浏览:416
中国游戏服务器如何用 发布:2024-10-31 08:16:23 浏览:629
查看linux内存使用率 发布:2024-10-31 08:14:25 浏览:48
华为低配置怎么样弄深夜模式 发布:2024-10-31 08:13:32 浏览:521
光遇安卓高马尾什么时候复刻 发布:2024-10-31 08:13:30 浏览:584
rust编译参数 发布:2024-10-31 08:11:25 浏览:295