??xml version="1.0" encoding="utf-8" standalone="yes"?>丁香婷婷久久久综合精品国产 ,亚洲国产精品网站,6699嫩草久久久精品影院http://www.aygfsteel.com/xulong/zh-cnThu, 19 Jun 2025 19:50:46 GMTThu, 19 Jun 2025 19:50:46 GMT60关于多线E?/title><link>http://www.aygfsteel.com/xulong/archive/2008/08/14/222123.html</link><dc:creator>虫子</dc:creator><author>虫子</author><pubDate>Thu, 14 Aug 2008 15:59:00 GMT</pubDate><guid>http://www.aygfsteel.com/xulong/archive/2008/08/14/222123.html</guid><wfw:comment>http://www.aygfsteel.com/xulong/comments/222123.html</wfw:comment><comments>http://www.aygfsteel.com/xulong/archive/2008/08/14/222123.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/xulong/comments/commentRss/222123.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/xulong/services/trackbacks/222123.html</trackback:ping><description><![CDATA[<div class="wmqeeuq" id="container"> <div class="wmqeeuq" id="header"> <h1 class="title">转至:(胜哥)<a >【虎.无名】学习Blog</a></h1> </div> <div class="wmqeeuq" id="category"><a title="上一? >|络行业协会点名十大氓软g</a>- -| <a >回首?/a> | <a >2005q烦?/a> | - -<a title="下一? >Ҏlog4j自带的FAQ译</a></div> <div id="wmqeeuq" class="entity"> <h2 class="diaryTitle">Java 多线E编E?wait/notify) - -</h2> <p>                                       <p> <p><a >Java 多线E编E?/a></p> <p>我们不妨设想Qؓ了创Z个新的线E,我们需要做些什么?很显Ӟ我们必须指明q个U程所要执行的代码Q而这是在Java中实现多U程我们所需要做的一切! </p> <p>真是奇QJava是如何做到这一点的Q通过c!作ؓ一个完全面向对象的语言QJava提供了类 java.lang.Thread 来方便多U程~程Q这个类提供了大量的Ҏ来方便我们控制自q各个U程Q我们以后的讨论都将围绕q个c进行?nbsp;      </p> <p> <p>那么如何提供l?Java 我们要线E执行的代码呢?让我们来看一?Thread cRThread cL重要的方法是 run() Q它为Thread cȝҎ start() 所调用Q提供我们的U程所要执行的代码。ؓ了指定我们自q代码Q只需要覆盖它Q?/p> <p> </p> <p>Ҏ一Q?Thread c,覆盖Ҏ run()</p> <p> </p> <p>我们在创建的 Thread cȝ子类中重?run() ,加入U程所要执行的代码卛_?/p> <p>下面是一个例子:</p> <p>package demoerror;</p> <p>public class MyThread<br />     extends Thread {<br />   int count = 1, number;<br />   public MyThread(int num) {<br />     number = num;<br />     System.out.println("创徏U程 " + number);<br />   }</p> <p>  public void run() {<br />     while (true) {<br />       System.out.println("U程 " + number + ":计数 " + count);<br />       if (++count == 6)return;<br />     }<br />   }</p> <p>  public static void main(String args[]) {<br />     for (int i = 0; i < 5; i++)new MyThread(i + 1).start();<br />   }<br /> }<br />  </p> <p>    q种Ҏ单明了,W合大家的习惯,但是Q它也有一个很大的~点Q那是如果我们的类已经从一个类l承Q如程序必ȝ承自 Applet c)Q则无法再?Thread c,q时如果我们又不惛_立一个新的类Q应该怎么办呢Q?/p> <p> <p>我们不妨来探索一U新的方法:我们不创?Thread cȝ子类Q而是直接使用它,那么我们只能我们的Ҏ作ؓ参数传递给 Thread cȝ实例Q有点类似回调函数。但?Java 没有指针Q我们只能传递一个包含这个方法的cȝ实例。那么如何限制这个类必须包含q一Ҏ呢?当然是用接口!Q虽然抽象类也可满Q但是需要承,而我们之所以要采用q种新方法,不就是ؓ了避免承带来的限制吗?Q?/p> <p> </p> <p>    Java 提供了接?java.lang.Runnable 来支持这U方法?/p> <p> <p>Ҏ二:实现 Runnable 接口</p> <p> </p> <p>Runnable 接口只有一个方?run()Q我们声明自qcd?Runnable 接口q提供这一ҎQ将我们的线E代码写入其中,完成了q一部分的Q务?/p> <p>但是 Runnable 接口q没有Q何对U程的支持,我们q必d?Thread cȝ实例Q这一炚w过 Thread cȝ构造函?/p> <p>public Thread(Runnable target);</p> <p>来实现?/p> <p>下面是一个例子:</p> <p>public class MyThread<br />     implements Runnable {<br />   int count = 1, number;<br />   public MyThread(int num) {<br />     number = num;<br />     System.out.println("创徏U程 " + number);<br />   }</p> <p>  public void run() {<br />     while (true) {<br />       System.out.println("U程 " + number + ":计数 " + count);<br />       if (++count == 6)return;<br />     }<br />   }</p> <p>  public static void main(String args[]) {<br />     for (int i = 0; i < 5; i++)new Thread(new MyThread(i + 1)).start();<br />   }</p> <p>}<br />  </p> <p>严格地说Q创?Thread 子类的实例也是可行的Q但是必L意的是,该子cdL有覆?Thread cȝ run ҎQ否则该U程执行的将是子cȝ run ҎQ而不是我</p> <p>们用以实现Runnable 接口的类?run ҎQ对此大家不妨试验一下?/p> <p> <p>使用 Runnable 接口来实现多U程使得我们能够在一个类中包Ҏ有的代码Q有利于装Q它的缺点在于,我们只能使用一套代码,若想创徏多个U程q各个U程执行不同的代码,则仍必须额外创徏c,如果q样的话Q在大多数情况下也许q不如直接用多个cd别?Thread 来得紧凑?/p> <p> </p> <p>lg所qͼ两种Ҏ各有千秋Q大家可以灵z运用?/p> <p> </p> <p>下面让我们一h研究一下多U程使用中的一些问题?/p> <p> <p>三:U程的四U状?/p> <p> <p>1. 新状态:U程已被创徏但尚未执行(start() 未被调用)?/p> <p>2. 可执行状态:U程可以执行Q虽然不一定正在执行。CPU 旉随时可能被分配给该线E,从而得它执行?/p> <p>3. M状态:正常情况?run() q回使得U程M。调?stop()?destroy() 亦有同样效果Q但是不被推荐,前者会产生异常Q后者是强制l止Q不会释N?/p> <p>4. d状态:U程不会被分?CPU 旉Q无法执行?/p> <p> <p>四:U程的优先</p> <p> <p>U程的优先代表该线E的重要E度Q当有多个线E同时处于可执行状态ƈ{待获得 CPU 旉ӞU程调度pȝҎ各个U程的优先来决定给谁分?CPU 旉Q优先高的U程有更大的Z获得 CPU 旉Q优先低的U程也不是没有机会,只是Z要小一些Ş了?/p> <p> </p> <p>你可以调?Thread cȝҎ getPriority() ?setPriority()来存取线E的优先U,U程的优先界于1(MIN_PRIORITY)?0(MAX_PRIORITY)之间Q缺省是5(NORM_PRIORITY)?/p> <p> <p>五:U程的同?/p> <p> <p>׃同一q程的多个线E共享同一片存储空_在带来方便的同时Q也带来了访问冲H这个严重的问题。Java语言提供了专门机制以解决q种冲突Q有效避免了同一个数据对象被多个U程同时讉K?/p> <p> </p> <p>׃我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对Ҏ提出一套机Ӟq套机制是 synchronized 关键字,它包括两U用法:synchronized Ҏ?synchronized 块?/p> <p> <p>1. synchronized ҎQ通过在方法声明中加入 synchronized关键字来声明 synchronized Ҏ。如Q?/p> <p>  public synchronized void accessVal(int newVal);</p> <p> </p> <p>    synchronized Ҏ控制对类成员变量的访问:每个cd例对应一把锁Q每?synchronized Ҏ都必获得调用该Ҏ的类实例的锁方能执行Q否则所属线E阻塞,?/p> <p>法一旦执行,q占该锁,直到从该Ҏq回时才锁释放Q此后被d的线E方能获得该锁,重新q入可执行状态。这U机制确保了同一时刻对于每一个类实例Q其所有声明ؓ synchronized 的成员函C臛_只有一个处于可执行状态(因ؓ臛_只有一个能够获得该cd例对应的锁)Q从而有效避免了cL员变量的讉K冲突Q只要所有可能访问类成员变量的方法均被声明ؓ synchronizedQ?/p> <p> </p> <p>    ?Java 中,不光是类实例Q每一个类也对应一把锁Q这h们也可将cȝ静态成员函数声明ؓ synchronized Q以控制其对cȝ静态成员变量的讉K?/p> <p> <p>synchronized Ҏ的缺P若将一个大的方法声明ؓsynchronized 会大大影响效率Q典型地Q若线E类的方?run() 声明?synchronized Q由于在U程的整个生命期内它一直在q行Q因此将D它对本类M synchronized Ҏ的调用都永远不会成功。当然我们可以通过访问类成员变量的代码放C门的Ҏ中,其声明?synchronized Qƈ在主Ҏ中调用来解决q一问题Q但?Java 为我们提供了更好的解军_法,那就?synchronized 块?/p> <p> <p>2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:</p> <p>   </p> <p>    synchronized(syncObject) {</p> <p>//允许讉K控制的代?/p> <p>    }</p> <p>   </p> <p>synchronized 块是q样一个代码块Q其中的代码必须获得对象 syncObject Q如前所qͼ可以是类实例或类Q的锁方能执行,具体机制同前所q。由于可以针对Q意代码块Q且可Q意指定上锁的对象Q故灉|性较高?/p> <p> <p>六:U程的阻?/p> <p> <p>Z解决对共享存储区的访问冲H,Java 引入了同步机Ӟ现在让我们来考察多个U程对共享资源的讉KQ显然同步机制已l不够了Q因为在L时刻所要求的资源不一定已l准备好了被讉KQ反q来Q同一时刻准备好了的资源也可能不止一个。ؓ了解册U情况下的访问控刉题,Java 引入了对d机制的支持?/p> <p> </p> <p>d指的是暂停一个线E的执行以等待某个条件发生(如某资源qAQ,学过操作pȝ的同学对它一定已l很熟悉了。Java 提供了大量方法来支持dQ下面让我们逐一分析?/p> <p> <p>1. sleep() ҎQsleep() 允许 指定以毫Uؓ单位的一D|间作为参敎ͼ它得线E在指定的时间内q入d状态,不能得到CPU 旉Q指定的旉一q,U程重新q入可执行状态?/p> <p>典型圎ͼsleep() 被用在等待某个资源就l的情ŞQ测试发现条件不满后,让线E阻塞一D|间后重新试Q直到条件满ؓ止?/p> <p> </p> <p>2. suspend() ?resume() ҎQ两个方法配套用,suspend()使得U程q入d状态,q且不会自动恢复Q必d对应的resume() 被调用,才能使得U程重新q入可执行状态。典型地Qsuspend() ?resume() 被用在等待另一个线E生的l果的情形:试发现l果q没有生后Q让U程dQ另一个线E生了l果后,调用 resume() 使其恢复?/p> <p> </p> <p>3. yield() ҎQyield() 使得U程攑ּ当前分得?CPU 旉Q但是不使线E阻塞,即线E仍处于可执行状态,随时可能再次分得 CPU 旉。调?yield() 的效果等价于调度E序认ؓ该线E已执行了够的旉从而{到另一个线E?/p> <p> <p>4. wait() ?notify() ҎQ两个方法配套用,wait() 使得U程q入d状态,它有两种形式Q一U允?指定以毫Uؓ单位的一D|间作为参敎ͼ另一U没有参敎ͼ前者当对应?notify() 被调用或者超出指定时间时U程重新q入可执行状态,后者则必须对应?notify() 被调用?/p> <p>      初看h它们?suspend() ?resume() ҎҎ有什么分别,但是事实上它们是截然不同的。区别的核心在于Q前面叙q的所有方法,d旉不会释放占用的锁Q如果占用了的话Q,而这一Ҏ法则相反?/p> <p>   </p> <p>上述的核心区别导致了一pd的细节上的区别?/p> <p>    首先Q前面叙q的所有方法都隶属?Thread c,但是q一对却直接隶属?Object c,也就是说Q所有对象都拥有q一Ҏ法。初看v来这十分不可思议Q但是实际上却是很自然的Q因一Ҏ法阻塞时要释攑֍用的锁,而锁是Q何对象都h的,调用L对象?wait() ҎDU程dQƈ且该对象上的锁被释放。而调?L对象的notify()Ҏ则导致因调用该对象的 wait() Ҏ而阻塞的U程中随机选择的一个解除阻塞(但要{到获得锁后才真正可执行Q?/p> <p>    其次Q前面叙q的所有方法都可在M位置调用Q但是这一Ҏ法却必须?synchronized Ҏ或块中调用,理由也很单,只有在synchronized Ҏ或块中当前线E才占有锁,才有锁可以释放。同L道理Q调用这一Ҏ法的对象上的锁必Mؓ当前U程所拥有Q这h有锁可以释放。因此,q一Ҏ法调用必L|在q样?synchronized Ҏ或块中,该方法或块的上锁对象是调用q一Ҏ法的对象。若不满一条gQ则E序虽然仍能~译Q但在运行时会出现IllegalMonitorStateException 异常?nbsp;  </p> <p><u>wait() ?notify() Ҏ的上q特性决定了它们l常和synchronized Ҏ或块一起用,它们和操作pȝ的进E间通信机制作一个比较就会发现它们的怼性:synchronizedҎ或块提供了类g操作pȝ原语的功能,它们的执行不会受到多U程机制的干扎ͼ而这一Ҏ法则相当?block 和wakeup 原语Q这一Ҏ法均声明?synchronizedQ?/u>它们的结合得我们可以实现操作系l上一pd_֦的进E间通信的算法(如信号量法Q,q用于解军_U复杂的U程间通信问题?nbsp;  </p> <p><strong>关于 wait() ?notify() Ҏ最后再说明两点Q?/strong></p> <p>    W一Q调?notify() ҎD解除d的线E是从因调用该对象的 wait() Ҏ而阻塞的U程中随机选取的,我们无法预料哪一个线E将会被选择Q所以编E时要特别小心,避免因这U不定性而生问题?/p> <p>    W二Q除?notify()Q还有一个方?notifyAll() 也可起到cM作用Q?u>唯一的区别在于,调用 notifyAll() Ҏ把因调用该对象?wait() Ҏ而阻塞的所有线E一ơ性全部解除阻塞?/u>当然Q只有获得锁的那一个线E才能进入可执行状态?/p> <p> <p>谈到dQ就不能不谈一谈死锁,略一分析p发现Q?u>suspend() Ҏ和不指定时期限?wait() Ҏ的调用都可能产生死锁。遗憄是,Java q不在语aU别上支持死锁的避免Q我们在~程中必d心地避免死锁?nbsp;  </u></p> <p>以上我们?Java 中实现线E阻塞的各种Ҏ作了一番分析,?u>们重点分析了 wait() ?notify() ҎQ因为它们的功能最强大Q用也最灉|Q但是这也导致了它们的效率较低,较容易出错。实际用中我们应该灉|使用各种ҎQ以便更好地辑ֈ我们的目的?/u></p> <p> <p><strong>七:守护U程</strong></p> <p> <p>    <u>守护U程是一cȝD的U程Q它和普通线E的区别在于它ƈ不是应用E序的核心部分,当一个应用程序的所有非守护U程l止q行Ӟ即仍然有守护线E在q行Q应用程序也终止,反之Q只要有一个非守护U程在运行,应用E序׃会终止。守护线E一般被用于在后Cؓ其它U程提供服务?/u></p> <p> </p> <p>    可以通过调用Ҏ isDaemon() 来判断一个线E是否是守护U程Q也可以调用Ҏ setDaemon() 来将一个线E设为守护线E?/p> <p> <p>八:U程l?/p> <p> <p>    U程l是一?Java Ҏ的概念,?Java 中,U程l是cThreadGroup 的对象,每个U程都隶属于唯一一个线E组Q这个线E组在线E创建时指定q在U程的整个生命期内都不能更改。你可以通过调用包含 ThreadGroup cd参数?Thread cL造函数来指定U程属的U程l,<u>若没有指定,则线E缺省地隶属于名?system 的系l线E组。 </u></p> <p>   <u> ?Java 中,除了预徏的系l线E组外,所有线E组都必L式创建?/u></p> <p> <p>    ?Java 中,除系l线E组外的每个U程l又隶属于另一个线E组Q你可以在创建线E组时指定其所隶属的线E组Q若没有指定Q则~省地隶属于pȝU程l。这P所有线E组l成了一以pȝU程lؓ根的树。 </p> <p>    Java 允许我们对一个线E组中的所有线E同时进行操作,比如我们可以通过调用U程l的相应Ҏ来设|其中所有线E的优先U,也可以启动或d其中的所有线E?/p> <p> <p>    <u>Java 的线E组机制的另一个重要作用是U程安全。线E组机制允许我们通过分组来区分有不同安全Ҏ的U程Q对不同l的U程q行不同的处理,q可以通过U程l的分层l构来支持不对等安全措施的采用。Java ?ThreadGroup cL供了大量的方法来方便我们对线E组树中的每一个线E组以及U程l中的每一个线E进行操作?/u></p> <p> <p>九:ȝ</p> <p> <p>    在这一讲中Q我们一起学习了 Java 多线E编E的Ҏ面面Q包括创建线E,以及对多个线E进行调度、管理。我们深刻认识到了多U程~程的复杂性,以及U程切换开销带来的多U程E序的低效性,q也促我们认真地思考一个问题:我们是否需要多U程Q何旉要多U程Q </p> <p>    多线E的核心在于多个代码块ƈ发执行,本质特点在于各代码块之间的代码是乱序执行的。我们的E序是否需要多U程Q就是要看这是否也是它的内在特点?/p> <p> <p>    假如我们的程序根本不要求多个代码块ƈ发执行,那自然不需要用多U程Q假如我们的E序虽然要求多个代码块ƈ发执行,但是却不要求乱序Q则我们完全可以用一个@环来单高效地实现Q也不需要用多U程Q只有当它完全符合多U程的特ҎQ多U程机制对线E间通信和线E管理的强大支持才能有用武之圎ͼq时使用多线E才是值得的?br /> </p>    <div align="right"><span id="wmqeeuq" class="basic-title-style">致命英雄@2005-2-19 20:15:30</span></div> <p> </p> <p class="diaryFoot">- 作者: <a onclick="window.open('http://publishblog.blogdriver.com/blog/postMessage.b?receiver=130163','发送短消息','width=520, height=455')" href="javascript:void(0);">nike_liu</a> 2005q?7?2? 星期?10:18 </p> </div> <div id="wmqeeuq" class="operation"><a name="trackback"> <h3>Trackback</h3> </a> <p class="trackback">你可以用这个链接引用该日?http://publishblog.blogdriver.com/blog/tb.b?diaryID=808011 </p> </div> <div id="wmqeeuq" class="operation"><a name="comment"> <h3>回复:׃本h在开发过E中遇到了类似问?苦思不得其?费了宝늚旉,最后在同事胜哥的博客中扑ֈ了答?希望能给大家带来一些帮?</h3> <p>胜哥z?Zh默默无闻,好学上进,是公司最为可靠的技术力?</p> </a></div> </div> <img src ="http://www.aygfsteel.com/xulong/aggbug/222123.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/xulong/" target="_blank">虫子</a> 2008-08-14 23:59 <a href="http://www.aygfsteel.com/xulong/archive/2008/08/14/222123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对Excel表格的读写操?/title><link>http://www.aygfsteel.com/xulong/archive/2008/06/09/206786.html</link><dc:creator>虫子</dc:creator><author>虫子</author><pubDate>Mon, 09 Jun 2008 08:33:00 GMT</pubDate><guid>http://www.aygfsteel.com/xulong/archive/2008/06/09/206786.html</guid><wfw:comment>http://www.aygfsteel.com/xulong/comments/206786.html</wfw:comment><comments>http://www.aygfsteel.com/xulong/archive/2008/06/09/206786.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/xulong/comments/commentRss/206786.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/xulong/services/trackbacks/206786.html</trackback:ping><description><![CDATA[     摘要: java对Excel表格的操?nbsp; <a href='http://www.aygfsteel.com/xulong/archive/2008/06/09/206786.html'>阅读全文</a><img src ="http://www.aygfsteel.com/xulong/aggbug/206786.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/xulong/" target="_blank">虫子</a> 2008-06-09 16:33 <a href="http://www.aygfsteel.com/xulong/archive/2008/06/09/206786.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ű</a>| <a href="http://" target="_blank">Ͽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ĩ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̰</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¡</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӳ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">ԫ</a>| <a href="http://" target="_blank">ϲ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǿ</a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">Ӧ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʯɽ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>