??xml version="1.0" encoding="utf-8" standalone="yes"?>在线亚洲欧美专区二区,国产精品久久久久免费a∨大胸,国产 日韩 欧美 综合 一区http://www.aygfsteel.com/tornado/category/23969.htmlzh-cnWed, 11 Jul 2007 12:40:44 GMTWed, 11 Jul 2007 12:40:44 GMT60- java单根l承体系http://www.aygfsteel.com/tornado/articles/129343.htmltornadotornadoTue, 10 Jul 2007 06:49:00 GMThttp://www.aygfsteel.com/tornado/articles/129343.htmlhttp://www.aygfsteel.com/tornado/comments/129343.htmlhttp://www.aygfsteel.com/tornado/articles/129343.html#Feedback0http://www.aygfsteel.com/tornado/comments/commentRss/129343.htmlhttp://www.aygfsteel.com/tornado/services/trackbacks/129343.html1、单根承中的所有对象都有共通接口,所以最l他们都属于相同的type?br>2、当完全OOP时必L造承体p,java中的单根l承体系保证所有对象都拥有某些功能Qheap堆之中生所有对象,大大化引C递动作?br>3、单根承体pM垃圾回收器更加容易。所有的必备功能都可以安|于base classw上。然后垃圑֛收器便可以发送适当的消息给pȝ中的每一个对象。如果缺乏单根承体pd完全通过reference来操作对象的pȝҎ。垃圑֛收器的实C׃十分困难?br>

]]> - JAVA多线E机?http://www.aygfsteel.com/tornado/articles/129152.htmltornadotornadoMon, 09 Jul 2007 14:04:00 GMThttp://www.aygfsteel.com/tornado/articles/129152.htmlhttp://www.aygfsteel.com/tornado/comments/129152.htmlhttp://www.aygfsteel.com/tornado/articles/129152.html#Feedback0http://www.aygfsteel.com/tornado/comments/commentRss/129152.htmlhttp://www.aygfsteel.com/tornado/services/trackbacks/129152.html
多线E是q样一U机Ӟ它允许在E序中ƈ发执行多个指令流Q每个指令流都称Z个线E,彼此间互相独立?br>
U程又称量q程Q它和进E一h有独立的执行控制Q由操作pȝ负责调度Q区别在于线E没有独立的存储I间Q而是和所属进E中的其它线E共享一个存储空_q得线E间的通信q较q程单?br>
多个U程的执行是q发的,也就是在逻辑?#8220;同时”Q而不是否是物理上的“同时”。如果系l只有一个CPUQ那么真正的“同时”是不可能的,但是׃CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它Q只需要设惛_个线E是同时执行卛_?br>
多线E和传统的单U程在程序设计上最大的区别在于Q由于各个线E的控制彼此独立,使得各个U程之间的代码是乱序执行的,由此带来的线E调度,同步{问题,在以后探讨?br>
二、在Java中实现多U程
我们不妨设想Qؓ了创Z个新的线E,我们需要做些什么?很显Ӟ我们必须指明q个U程所要执行的代码Q而这是在Java中实现多U程我们所需要做的一切!
真是奇QJava是如何做到这一点的Q通过c!作ؓ一个完全面向对象的语言QJava提供了类java.lang.Thread来方便多U程~程Q这个类提供了大量的Ҏ来方便我们控制自q各个U程Q我们以后的讨论都将围绕q个c进行?br>
那么如何提供l?nbsp;Java 我们要线E执行的代码呢?让我们来看一?nbsp;Thread cRThread cL重要的方法是run()Q它为ThreadcȝҎstart()所调用Q提供我们的U程所要执行的代码。ؓ了指定我们自q代码Q只需要覆盖它Q?br>
Ҏ一Q?nbsp;Thread c,覆盖Ҏ run()Q我们在创徏?nbsp;Thread cȝ子类中重?nbsp;run() ,加入U程所要执行的代码卛_。下面是一个例子:
public class MyThread extends Thread
{
int count= 1, number;
public MyThread(int num)
{
number = num;
System.out.println
("创徏U程 " + number);
}
public void run() {
while(true) {
System.out.println
("U程 " + number + ":计数 " + count);
if(++count== 6) return;
}
}
public static void main(String args[])
{
for(int i = 0;
i ?nbsp;5; i++) new MyThread(i+1).start();
}
}
q种Ҏ单明了,W合大家的习惯,但是Q它也有一个很大的~点Q那是如果我们的类已经从一个类l承Q如程序必ȝ承自 Applet c)Q则无法再?nbsp;Thread c,q时如果我们又不惛_立一个新的类Q应该怎么办呢Q?br>
我们不妨来探索一U新的方法:我们不创建Threadcȝ子类Q而是直接使用它,那么我们只能我们的Ҏ作ؓ参数传递给 Thread cȝ实例Q有点类似回调函数。但?nbsp;Java 没有指针Q我们只能传递一个包含这个方法的cȝ实例?br>
那么如何限制q个cdd含这一Ҏ呢?当然是用接口!Q虽然抽象类也可满Q但是需要承,而我们之所以要采用q种新方法,不就是ؓ了避免承带来的限制吗?Q?br>
Java 提供了接?nbsp;java.lang.Runnable 来支持这U方法?br>
Ҏ二:实现 Runnable 接口
Runnable接口只有一个方法run()Q我们声明自qcd现Runnable接口q提供这一ҎQ将我们的线E代码写入其中,完成了q一部分的Q务。但是Runnable接口q没有Q何对U程的支持,我们q必d建Threadcȝ实例Q这一炚w过Threadcȝ构造函?nbsp;public Thread(Runnable target);来实现。下面是一个例子:
public class MyThread implements Runnable
{
int count= 1, number;
public MyThread(int num)
{
number = num;
System.out.println("创徏U程 " + number);
}
public void run()
{
while(true)
{
System.out.println
("U程 " + number + ":计数 " + count);
if(++count== 6) return;
}
}
public static void main(String args[])
{
for(int i = 0; i ?nbsp;5;
i++) new Thread(new MyThread(i+1)).start();
}
}
严格地说Q创建Thread子类的实例也是可行的Q但是必L意的是,该子cdL有覆?nbsp;Thread cȝ run ҎQ否则该U程执行的将是子cȝ run ҎQ而不是我们用以实现Runnable 接口的类?nbsp;run ҎQ对此大家不妨试验一下?br>
使用 Runnable 接口来实现多U程使得我们能够在一个类中包Ҏ有的代码Q有利于装Q它的缺点在于,我们只能使用一套代码,若想创徏多个U程q各个U程执行不同的代码,则仍必须额外创徏c,如果q样的话Q在大多数情况下也许q不如直接用多个cd别?nbsp;Thread 来得紧凑?br>
lg所qͼ两种Ҏ各有千秋Q大家可以灵z运用?br>
下面让我们一h研究一下多U程使用中的一些问题?br>
三、线E的四种状?br>
1. 新状态:U程已被创徏但尚未执行(start() 未被调用)?br>
2. 可执行状态:U程可以执行Q虽然不一定正在执行。CPU 旉随时可能被分配给该线E,从而得它执行?br>
3. M状态:正常情况?nbsp;run() q回使得U程M。调?nbsp;stop()?nbsp;destroy() 亦有同样效果Q但是不被推荐,前者会产生异常Q后者是强制l止Q不会释N?br>
4. d状态:U程不会被分?nbsp;CPU 旉Q无法执行?br>
四、线E的优先U?br>
U程的优先代表该线E的重要E度Q当有多个线E同时处于可执行状态ƈ{待获得 CPU 旉ӞU程调度pȝҎ各个U程的优先来决定给谁分?nbsp;CPU 旉Q优先高的U程有更大的Z获得 CPU 旉Q优先低的U程也不是没有机会,只是Z要小一些Ş了?br>
你可以调?nbsp;Thread cȝҎ getPriority() ?nbsp;setPriority()来存取线E的优先U,U程的优先界于1(MIN_PRIORITY)?0(MAX_PRIORITY)之间Q缺省是5(NORM_PRIORITY)?br>
五、线E的同步
׃同一q程的多个线E共享同一片存储空_在带来方便的同时Q也带来了访问冲H这个严重的问题。Java语言提供了专门机制以解决q种冲突Q有效避免了同一个数据对象被多个U程同时讉K?br>
׃我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对Ҏ提出一套机Ӟq套机制是 synchronized 关键字,它包括两U用法:synchronized Ҏ?nbsp;synchronized 块?br>
1. synchronized ҎQ通过在方法声明中加入 synchronized关键字来声明 synchronized Ҏ。如Q?br>
public synchronized void accessVal(int newVal);
synchronized Ҏ控制对类成员变量的访问:每个cd例对应一把锁Q每?nbsp;synchronized Ҏ都必获得调用该Ҏ的类实例的锁方能执行Q否则所属线E阻塞,Ҏ一旦执行,q占该锁,直到从该Ҏq回时才锁释放Q此后被d的线E方能获得该锁,重新q入可执行状态?br>
q种机制保了同一时刻对于每一个类实例Q其所有声明ؓ synchronized 的成员函C臛_只有一个处于可执行状态(因ؓ臛_只有一个能够获得该cd例对应的锁)Q从而有效避免了cL员变量的讉K冲突Q只要所有可能访问类成员变量的方法均被声明ؓ synchronizedQ?br>
?nbsp;Java 中,不光是类实例Q每一个类也对应一把锁Q这h们也可将cȝ静态成员函数声明ؓ synchronized Q以控制其对cȝ静态成员变量的讉K?br>
synchronized Ҏ的缺P若将一个大的方法声明ؓsynchronized 会大大影响效率Q典型地Q若线E类的方?nbsp;run() 声明?nbsp;synchronized Q由于在U程的整个生命期内它一直在q行Q因此将D它对本类M synchronized Ҏ的调用都永远不会成功。当然我们可以通过访问类成员变量的代码放C门的Ҏ中,其声明?nbsp;synchronized Qƈ在主Ҏ中调用来解决q一问题Q但?nbsp;Java 为我们提供了更好的解军_法,那就?nbsp;synchronized 块?br>
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject)
{
//允许讉K控制的代?br> }
synchronized 块是q样一个代码块Q其中的代码必须获得对象 syncObject Q如前所qͼ可以是类实例或类Q的锁方能执行,具体机制同前所q。由于可以针对Q意代码块Q且可Q意指定上锁的对象Q故灉|性较高?br>
六、线E的d
Z解决对共享存储区的访问冲H,Java 引入了同步机Ӟ现在让我们来考察多个U程对共享资源的讉KQ显然同步机制已l不够了Q因为在L时刻所要求的资源不一定已l准备好了被讉KQ反q来Q同一时刻准备好了的资源也可能不止一个。ؓ了解册U情况下的访问控刉题,Java 引入了对d机制的支持?br>
d指的是暂停一个线E的执行以等待某个条件发生(如某资源qAQ,学过操作pȝ的同学对它一定已l很熟悉了。Java 提供了大量方法来支持dQ下面让我们逐一分析?br>
1. sleep() ҎQsleep() 允许指定以毫Uؓ单位的一D|间作为参敎ͼ它得线E在指定的时间内q入d状态,不能得到CPU 旉Q指定的旉一q,U程重新q入可执行状态。典型地Qsleep() 被用在等待某个资源就l的情ŞQ测试发现条件不满后,让线E阻塞一D|间后重新试Q直到条件满ؓ止?br>
2. suspend() ?nbsp;resume() ҎQ两个方法配套用,suspend()使得U程q入d状态,q且不会自动恢复Q必d对应的resume() 被调用,才能使得U程重新q入可执行状态。典型地Qsuspend() ?nbsp;resume() 被用在等待另一个线E生的l果的情形:试发现l果q没有生后Q让U程dQ另一个线E生了l果后,调用 resume() 使其恢复?br>
3. yield() ҎQyield() 使得U程攑ּ当前分得?nbsp;CPU 旉Q但是不使线E阻塞,即线E仍处于可执行状态,随时可能再次分得 CPU 旉。调?nbsp;yield() 的效果等价于调度E序认ؓ该线E已执行了够的旉从而{到另一个线E?br>
4. wait() ?nbsp;notify() ҎQ两个方法配套用,wait() 使得U程q入d状态,它有两种形式Q一U允许指定以毫秒为单位的一D|间作为参敎ͼ另一U没有参敎ͼ前者当对应?nbsp;notify() 被调用或者超出指定时间时U程重新q入可执行状态,后者则必须对应?nbsp;notify() 被调用?br>
初看h它们?nbsp;suspend() ?nbsp;resume() ҎҎ有什么分别,但是事实上它们是截然不同的。区别的核心在于Q前面叙q的所有方法,d旉不会释放占用的锁Q如果占用了的话Q,而这一Ҏ法则相反?br>
上述的核心区别导致了一pd的细节上的区别?br>
首先Q前面叙q的所有方法都隶属?nbsp;Thread c,但是q一对却直接隶属?nbsp;Object c,也就是说Q所有对象都拥有q一Ҏ法。初看v来这十分不可思议Q但是实际上却是很自然的Q因一Ҏ法阻塞时要释攑֍用的锁,而锁是Q何对象都h的,调用L对象?nbsp;wait() ҎDU程dQƈ且该对象上的锁被释放?br>
而调?nbsp;L对象的notify()Ҏ则导致因调用该对象的 wait() Ҏ而阻塞的U程中随机选择的一个解除阻塞(但要{到获得锁后才真正可执行Q?br>
其次Q前面叙q的所有方法都可在M位置调用Q但是这一Ҏ法却必须?nbsp;synchronized Ҏ或块中调用,理由也很单,只有在synchronized Ҏ或块中当前线E才占有锁,才有锁可以释放?br>
同样的道理,调用q一Ҏ法的对象上的锁必Mؓ当前U程所拥有Q这h有锁可以释放。因此,q一Ҏ法调用必L|在q样?nbsp;synchronized Ҏ或块中,该方法或块的上锁对象是调用q一Ҏ法的对象。若不满一条gQ则E序虽然仍能~译Q但在运行时会出?nbsp;IllegalMonitorStateException 异常?br>
wait() ?nbsp;notify() Ҏ的上q特性决定了它们l常和synchronized Ҏ或块一起用,它们和操作pȝ的进E间通信机制作一个比较就会发现它们的怼性:synchronizedҎ或块提供了类g操作pȝ原语的功能,它们的执行不会受到多U程机制的干扎ͼ而这一Ҏ法则相当?nbsp;block 和wakeup 原语Q这一Ҏ法均声明?nbsp;synchronizedQ?br>
它们的结合得我们可以实现操作系l上一pd_֦的进E间通信的算法(如信号量法Q,q用于解军_U复杂的U程间通信问题。关?nbsp;wait() ?nbsp;notify() Ҏ最后再说明两点Q?br>
W一Q调?nbsp;notify() ҎD解除d的线E是从因调用该对象的 wait() Ҏ而阻塞的U程中随机选取的,我们无法预料哪一个线E将会被选择Q所以编E时要特别小心,避免因这U不定性而生问题?br>
W二Q除?nbsp;notify()Q还有一个方?nbsp;notifyAll() 也可起到cM作用Q唯一的区别在于,调用 notifyAll() Ҏ把因调用该对象?nbsp;wait() Ҏ而阻塞的所有线E一ơ性全部解除阻塞。当Ӟ只有获得锁的那一个线E才能进入可执行状态?br>
谈到dQ就不能不谈一谈死锁,略一分析p发现Qsuspend() Ҏ和不指定时期限?nbsp;wait() Ҏ的调用都可能产生死锁。遗憄是,Java q不在语aU别上支持死锁的避免Q我们在~程中必d心地避免死锁?br>
以上我们?nbsp;Java 中实现线E阻塞的各种Ҏ作了一番分析,我们重点分析?nbsp;wait() ?nbsp;notify()ҎQ因为它们的功能最强大Q用也最灉|Q但是这也导致了它们的效率较低,较容易出错。实际用中我们应该灉|使用各种ҎQ以便更好地辑ֈ我们的目的?br>
七、守护线E?br>
守护U程是一cȝD的U程Q它和普通线E的区别在于它ƈ不是应用E序的核心部分,当一个应用程序的所有非守护U程l止q行Ӟ即仍然有守护线E在q行Q应用程序也终止,反之Q只要有一个非守护U程在运行,应用E序׃会终止。守护线E一般被用于在后Cؓ其它U程提供服务?br>
可以通过调用Ҏ isDaemon() 来判断一个线E是否是守护U程Q也可以调用Ҏ setDaemon() 来将一个线E设为守护线E?br>
八、线E组
U程l是一?nbsp;Java Ҏ的概念,?nbsp;Java 中,U程l是cThreadGroup 的对象,每个U程都隶属于唯一一个线E组Q这个线E组在线E创建时指定q在U程的整个生命期内都不能更改?br>
你可以通过调用包含 ThreadGroup cd参数?nbsp;Thread cL造函数来指定U程属的U程l,若没有指定,则线E缺省地隶属于名?nbsp;system 的系l线E组?br>
?nbsp;Java 中,除了预徏的系l线E组外,所有线E组都必L式创建。在 Java 中,除系l线E组外的每个U程l又隶属于另一个线E组Q你可以在创建线E组时指定其所隶属的线E组Q若没有指定Q则~省地隶属于pȝU程l。这P所有线E组l成了一以pȝU程lؓ根的树?br>
Java 允许我们对一个线E组中的所有线E同时进行操作,比如我们可以通过调用U程l的相应Ҏ来设|其中所有线E的优先U,也可以启动或d其中的所有线E?br>
Java 的线E组机制的另一个重要作用是U程安全。线E组机制允许我们通过分组来区分有不同安全Ҏ的U程Q对不同l的U程q行不同的处理,q可以通过U程l的分层l构来支持不对等安全措施的采用?br>
Java ?nbsp;ThreadGroup cL供了大量的方法来方便我们对线E组树中的每一个线E组以及U程l中的每一个线E进行操作?br>
九、ȝ
在本文中Q我们讲qC Java 多线E编E的Ҏ面面Q包括创建线E,以及对多个线E进行调度、管理。我们深刻认识到了多U程~程的复杂性,以及U程切换开销带来的多U程E序的低效性,q也促我们认真地思考一个问题:我们是否需要多U程Q何旉要多U程Q?br>
多线E的核心在于多个代码块ƈ发执行,本质特点在于各代码块之间的代码是乱序执行的。我们的E序是否需要多U程Q就是要看这是否也是它的内在特点?br>
假如我们的程序根本不要求多个代码块ƈ发执行,那自然不需要用多U程Q假如我们的E序虽然要求多个代码块ƈ发执行,但是却不要求乱序Q则我们完全可以用一个@环来单高效地实现Q也不需要用多U程Q只有当它完全符合多U程的特ҎQ多U程机制对线E间通信和线E管理的强大支持才能有用武之圎ͼq时使用多线E才是值得的?nbsp;

]]>
վ֩ģ壺
|
|
|
|
ֹ|
|
Ļ|
ء|
|
¤|
ƴ|
Ʊ|
|
ͨ|
ָ|
ƽ|
|
Ϋ|
Ϫ|
ī|
ʯ|
ĵ|
ն|
|
|
Ԫ|
|
ͺ|
|
ƽ|
|
|
ʼ|
Ů|
|
|
|
|
|
|
|