免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1164 | 回复: 0
打印 上一主题 下一主题

Java线程学习 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-01 09:34 |只看该作者 |倒序浏览
作者:e全 来源:expert.blogjava.net  发布时间:2007-12-11 10:57:55.317
编写具有多线程能力的程序经常会用到的方法有:
  run(),start(),wait(),notify(),notifyAll(),sleep(),yield(),join()
  还有一个重要的关键字:synchronized
  本文将对以上内容进行讲解。
  一:run()和start()
  示例1:
public class ThreadTest extends Thread {
public void run() {
  for(int i=0; i二:关键字synchronized
  有了synchronized关键字,多线程程序的运行结果将变得可以控制。synchronized关键字用于保护共享数据。请大家注意"共享数据",你一定要分清哪些数据是共享数据,JAVA是面向对象的程序设计语言,所以初学者在编写多线程程序时,容易分不清哪些数据是共享数据。请看下面的例子:
  示例2:
  publicclassThreadTestimplementsRunnable{
  publicsynchronizedvoidrun(){
   for(inti=0;i三:sleep()
  示例6:
  publicclassThreadTestimplementsRunnable{
  publicvoidrun(){
   for(intk=0;k四:join()
  示例9:
  publicclassThreadTestimplementsRunnable{
  publicstaticinta=0;
  publicvoidrun(){
   for(intk=0;k五:yield()
  yield()方法与sleep()方法相似,只是它不能由用户指定线程暂停多长时间。按照SUN的说法:
  sleep方法可以使低优先级的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会。而yield()
  方法只能使同优先级的线程有执行的机会。
  示例11:
publicclassThreadTestimplementsRunnable{
  publicvoidrun(){
   8
     for(intk=0;k六:wait(),notify(),notifyAll()
  首先说明:wait(),notify(),notifyAll()这些方法由java.lang.Object类提供,而上面讲到的方法都是由java.lang.Thread类提供(Thread类实现了Runnable接口)。
  wait(),notify(),notifyAll()这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用这三个方法。先看下面了例子:
  示例12:
publicclassThreadTestimplementsRunnable{
  publicstaticintshareVar=0;
  publicsynchronizedvoidrun(){
   if(shareVar==0){
    for(inti=0;i七:关于线程的补充
  编写一个具有多线程能力的程序可以继承Thread类,也可以实现Runnable接口。在这两个方法中如何选择呢?从面向对象的角度考虑,作者建议你实现Runnable接口。有时你也必须实现Runnable接口,例如当你编写具有多线程能力的小应用程序的时候。
  线程的调度:NewRunningRunnableOtherwiseBlockedDeadBlockedinobject`sit()
  poolBlockedinobject`slockpoolnotify()Schedulercompletesrun()start()
  sleep()orjoin()sleep()timeoutorthreadjoin()sorinterupt()
  Lockavailablesynchronized()Threadstates
  terupt()一个Thread对象在它的生命周期中会处于各种不同的状态,上图形象地说明了这点。wain
  调用start()方法使线程处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。
  实际上,程序中的多个线程并不是同时执行的。除非线程正在真正的多CPU计算机系统上执行,否则线程使用单CPU必须轮流执行。但是,由于这发生的很快,我们常常认为这些线程是同时执行的。
  JAVA运行时系统的计划调度程序是抢占性的。如果计划调度程序正在运行一个线程并且来了另一个优先级更高的线程,那么当前正在执行的线程就被暂时终止而让更高优先级的线程执行。
  JAVA计划调度程序不会为与当前线程具有同样优先级的另一个线程去抢占当前的线程。但是,尽管计划调度程序本身没有时间片(即它没有给相同优先级的线程以执行用的时间片),但以Thread类为基础的线程的系统实现可能会支持时间片分配。这依赖具体的操作系统,Windows与UNIX在这个问题上的支持不会完全一样。
  由于你不能肯定小应用程序将运行在什么操作系统上,因此你不应该编写出依赖时间片分配的程序。就是说,应该使用yield方法以允许相同优先级的线程有机会执行而不是希望每一个线程都自动得到一段CPU时间片。
  Thread类提供给你与系统无关的处理线程的机制。但是,线程的实际实现取决于JAVA运行所在的操作系统。因此,线程化的程序确实是利用了支持线程的操作系统。
  当创建线程时,可以赋予它优先级。它的优先级越高,它就越能影响运行系统。
  JAVA运行系统使用一个负责在所有执行JAVA程序内运行所有存在的计划调度程序。
  该计划调度程序实际上使用一个固定优先级的算法来保证每个程序中的最高优先级的线程得到CPU--允许最高优先级的线程在其它线程之前执行。
  对于在一个程序中有几个相同优先级的线程等待执行的情况,该计划调度程序循环地选择它们,当进行下一次选择时选择前面没有执行的线程,
  具有相同优先级的所有的线程都受到平等的对待。较低优先级的线程在较高优先级的线程已经死亡或者进入不可执行状态之后才能执行。
  继续讨论wait(),notify(),notifyAll():
  当线程执行了对一个特定对象的wait()调用时,那个线程被放到与那个对象相关的等待池中。此外,调用wait()的线程自动释放对象的锁标志。
  可以调用不同的wait():wait()或wait(longtimeout)
  对一个特定对象执行notify()调用时,将从对象的等待池中移走一个任意的线程,并放到锁标志等待池中,那里的线程一直在等待,直到可以获得对象的锁标志。notifyAll()方法将从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
  只有锁标志等待池中的线程能获取对象的锁标志,锁标志允许线程从上次因调用wait()而中断的地方开始继续运行。
  在许多实现了wait()/notify()机制的系统中,醒来的线程必定是那个等待时间最长的线程。然而,在Java技术中,并不保证这点。
  注意,不管是否有线程在等待,都可以调用notify()。如果对一个对象调用notify()方法,而在这个对象的锁标志等待池中并没有线程,那么notify()调用将不起任何作用。
  在JAVA中,多线程是一个神奇的主题。之所以说它"神奇",是因为多线程程序的运行结果不可预测,但我们又可以通过某些方法控制多线程程序的执行。
  要想灵活使用多线程,读者还需要大量实践。
  另外,从JDK1.2开始,SUN就不建议使用resume(),stop(),suspend()了。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/6055/showart_1070332.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP