Chinaunix首页 | 论坛 | 博客
  • 博客访问: 194355
  • 博文数量: 69
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 720
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-03 11:35
文章分类

全部博文(69)

文章存档

2011年(13)

2010年(46)

2009年(10)

我的朋友

分类: Java

2010-01-27 15:16:22

JavaThread 100127Thread 简记

@ http://zcatt.cublog.cn


Hist

20060912, draft

20100127, update for cublog

20100722, add ThreadLocal etc.

1.Thread的基本问题

    Thread的基本问题包括,并行/并发Thread的创建和结束,同步互斥机制,和调度机制。

    Thread的创建很简单,有关的接口是java.lang.Runnable

    同步互斥机制是指解决不同线程之间的同步和资源竞争问题的方法体系。下文中有详述。

    java.lang.Thread中虽然有setPriority()/getPriority()方法,但程序员不应当对java的调度机制有过多的期望,实际上这部分是依赖于VM在不同OS上的实现的。通常的问题是想当然认为java是基于优先级的分时调度,这是不对的。JDK5 tutorial中确认sun java是基于优先级的,但不保证分时(timeslicing)。简单讲,设计中最好依赖于同步互斥而不要基于vm的调度。

 

2.Thread的基本用法

 

    代码如下:

 

       //implement your own runnable class

       class MyRunnable implements Runnable

       {

              public void run()

              {

                     ......

              }

       }

 

       //create your thread obj

       MyRunnable r = new MyRunnable(...);

       Thread t = new Thread(r);

 

       //run your thread

       t.start();

 

    创建thread很简单,首先定义自己的Runnable类,然后创建Thread,调用start方法就可以启动thread了,thread将执行Runnable中的run()方法。

    不推荐直接继承Thread类的编程方法。

 

3.Thread生命周期中的几个状态

 

    Thread的状态如下图。

 

       new state

       |

       | start

       |

       V

                     sleep,wait, block on I/O, wait for lock

       runnable state<--------------------------------------------------------> blocked state

                     done sleep,notify, IO complete, lock available

       |

       | stop / run() exist

       |

       V

       dead state

 

    Thread4个状态,new, runnable, blocked,和dead。有一点,runnable状态下的threadjava的调度下既可以正在执行也可以是在等待执行,runnable表明thread具有了被执行的资格,等待被调度执行。

    java.lang.Thread.State定义了6个状态:NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED

 

 

4.Object类对Thread的支持

 

    每个Oject类的实例拥有一个自己的lockjdk中称作monitor),一般情况下这个用作同步互斥的object就指的是Thread自己,因为Thread类的父类就是Object类。lock就是实现thread同步互斥的核心。Object类中有3个基本的方法:wait()notify(), notifyAll()

 

    Thread拥有某个object[*]lock时,它可以调用这个objectwait(),这样它就让出lock的所有权(ownership)而进入blocked state。直到其他thread调用这个objectnotify()notifyAll()方法唤醒它,并且同时它可以重新得到lock的所有权的时候,它才重新进入runnable state。如果其他thread调用了notify()/notifyAll(),而它无法重新得到lock的所有权,那么它仍然无法进入runnable state

 

    只有当thread拥有objectlock时,调用上面3个方法才有意义。那么什么叫“thread拥有了objectlock”呢? JDK中规定了在下述3种境况下就是“thread拥有了objectlock”,

        1thread正在执行用synchronized定义的object的实例方法(不是类方法)。

        2thread正在执行用synchronizedobject)定义的代码段。

        3)当thread正在执行类的synchronized静态方法时,认为thread拥有这个类对应的java.lang.Class实例的lock

 

    lock有两个基本的特性。第一个特性是一个时刻只能被一个thread拥有,也就是不可能有两个或两个以上的thread同时拥有同一个lock。这个性质保证了可以凭借lock实现thread间同步互斥。第二个特性是可重入性(reentrant,可重入性是指如果thread拥有某个lock,那么thread可以调用这个locksynchronized方法而不被阻塞,这就保证了thread不会被已经拥有的lock阻塞掉。

5.Daemon Thread

    Java中有一类特殊的thread,就是daemon thread。运行java应用程序,当程序中只有daemon thread时,java应用程序将退出。

    Thread.setDaemon(boolean on)可以将Thread设置为Daemon Thread

6.interrupt()

    thread处于blocked state时,如何告知thread诸如“应当退出了”等消息。interrupt机制可以实现这个任务。

    Thread对象内部有一个布尔状态量interrupt statusinterrupt状态),当调用interrupt()方法时会影响到这个布尔量。基本算法是这样的,

 

       1)如果threadrunnable state,那么调用interrupt()会设置interrupt statustrue

       2)如果threadblocked state()[**],那么调用interrupt()会清除interrupt statusfalse,并且触发threadInterruptException。([**]注,严格讲应当是阻塞在wait()join(),和sleep()上。详细查JDK。)

    利用2),blocked statethread可以及时处理各种紧急消息,通常是退出请求。

 

7. Not Selfish

   如果允许,请不要设计自私(selfish)thread,给其他的thread执行的机会,尤其在infinite loop情况下。自私的thread策略从根本上与使用多thread的初衷抵触。

   通常有两种实现避免selfish

   1)调用yield();

       2)调用sleep(0);

 

   两种方法的差异研究中。目前看,yield()更依赖于vm的调度策略,另外yield只会给同优先级的thread机会,不会给低优先级thread机会。在有同优先级thread存在的情况下,yield()肯定会使别的thread得到运行,而依赖于优先级调度,sleep(0)似乎就不见的(有待确认?)更多的答案可能要读一下vm的实现代码了。

8. Thread中的几个静态方法

      static Thread currentThread();

       static boolean interrupted();

       static void sleep(...);

       static void yield();

 

9. ThreadGroup

    ThreadGroup的主要目的是将多个Thread对象组织起来,便于操纵。一个ThreadGroup即可以包括多个Thread对象,也可以包含多个ThreadGroup,从而构成树状结构。向上遍历使用getParent(),向下遍历使用enumerate()

 

       int activeCount()

       返回ThreadGroup中活动Thread的数目(包括孙子等)。

 

       int activeGroupCount()

       返回ThreadGroup中活动子Group的数目(包括孙子等)。

 

10. ThreadLocalInheritableThreadLocal

ThreadLocal提供了一个变量针对多个thread存储各自对象的功能, 这个同win32中的TLS概念类似.

ThreadLocal4个方法:

protected T initialValue()

public T get()

public void set(T value)

public void remove()

 

其中get()set()分别是读和写. initialValue()是初始化操作, 两种情况下, initialValue()会被调用来执行初始化. 一种是, 第一次调用get(),如果之前未set(), initialValue()会被调用一次执行初始化, 后面的get()就不再调用initialValue(). 第二种情况, remove(), 直接调用get(). ThreadLocal的子类可以重新实现initialValue()实现自己特殊的初始化操作.

InheritableThreadLocal增加了一个方法childValue(), 子线程创建前, 在母线程中, childValue()将被调用来决定子线程中的InheritableThreadLocal的初始值. 籍此, 母线程可以控制子线程的InheritableThreadLocal的初始值.

 

11. JDK5中新增类的简述

TBD

 

12.参考与连接

1. JLS

2. Cay S. Horstman, Gary Cornell, Core Java 2 Valueme, 7Ed

3. Sun Microsystems, Inc, The Java Tutorial


Locations of visitors to this page
阅读(1424) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~