Thread.Sleep(0)
线程这一概念,可以理解成进程中的一个小单元。这个单元是一个独立的执行单元,但是与进程中的其他线程共享进程中的内存单元。
由于Cpu资源是有限的,所以进程中的多个线程要抢占Cpu,这也导致进程中的多个线程交替执行。
Thread.Sleep() 本身的含义是当前线程挂起一定时间。
Thread.Sleep(0) MSDN上的解释是挂起此线程能使其他等待线程执行。这样的解释容易导致误解,我们可以这样理解,其实是让当前线程挂起,使得其他线程可以和当前线程再次的抢占Cpu资源。
关于Thread的构造函数:
thread(this, ThreadName)对于Java中这个语句,this是什么?还有Thread为什么需要一个this?
首先,这是一个构造函数,SDK说明如下
public Thread(Runnable target,
String name)
Allocates a new Thread object. This constructor has the same effect as Thread (null, target, name).
Parameters:
target - the object whose run method is invoked when this thread is started. If null, this thread's run method is invoked.
name - the name of the new thread
两个参数Runnable和String类型,你的GetCurrentThread实现了Runnable接口,这里的this是代表当前对象,恰好这里的当前对象是一个Runnable。
Thread要的不是this
,它要一个
Runnable
,而,刚好
this
是一个
Runnable
interrupt方法
interrupt,顾名思义,即中断的意思。单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,也就说,它可以用来中断一个正处于阻塞状态的线程;另外,通过interrupt方法和isInterrupted()方法来停止正在运行的线程。
直接调用 interrupt方法不能中断正在运行中的线程根据API中的定义,Class.getSimpleName()方法是获取源代码中给出的‘底层类’简称 而Class.getName();以String的形式,返回Class对象的‘实体’名称
notifyAll():
Causes all threads which are waiting on this object's monitor (by means of calling one of the wait()
methods) to be woken up. The threads will not run immediately. The thread that called notify()
has to release the object's monitor first. Also, the threads still have to compete against other threads that try to synchronize on the same object.
This method can only be invoked by a thread which owns this object's monitor. A thread becomes owner of an object's monitor
- by executing a synchronized method of that object;
- by executing the body of a
synchronized
statement that synchronizes on the object; - by executing a synchronized static method if the object is of type
Class
.
还有:(wait/notify/notifyAll)只能在取得对象锁的时候才能调用。
调用notifyAll通知所有线程继续执行,只能有一个线程在执行其余的线程在等待(因为在所有线程被唤醒的时候在synchornized块中)。这时的等待和调用notifyAll前的等待是不一样的。
notifyAll前:在对象上休息区内休息
notifyAll后:在排队等待获得对象锁。
notify和notifyAll都是把某个对象上休息区内的线程唤醒,notify只能唤醒一个,但究竟是哪一个不能确定,而notifyAll则唤醒这个对象上的休息室中所有的线程.
一般有为了安全性,我们在 绝对多数 时候应该使用notifiAll(),除非你明确知道只唤醒其中的一个线程.
至于有些书上说“notify:唤醒同一对象监视器中调用 wait的第一个线程”我认为是没有 根据的因为 sun公司 是这样说的“The choice is arbitrary and occurs at the discretion of the implementation.”
Wait是Object类的方法,范围是使该Object实例所处的线程。
Sleep()是Thread类专属的静态方法,针对一个特定的线程。
Wait方法使实体所处线程暂停执行,从而使对象进入等待状态,直到被notify方法通知或者wait的等待的时间到。Sleep方法使持有的线程暂停运行,从而使线程进入休眠状态,直到用interrupt方法来打断他的休眠或者sleep的休眠的时间到。Wait方法进入等待状态时会释放同步锁(如上例中的lock对象),而Sleep方法不会释放同步锁。所以,当一个线程无限Sleep时又没有任何人去interrupt它的时候,程序就产生大麻烦了notify是用来通知线程,但在notify之前线程是需要获得lock的。另个意思就是必须写在synchronized(lockobj) {...}之中。wait也是这个样子,一个线程需要释放某个lock,也是在其获得lock情况下才能够释放,所以wait也需要放在synchronized(lockobj) {...}之中。
Sleep与interrupt
interrupt是个很暴力的方法,打断一个线程的Sleep时并不需要获得该线程的lock。虽然暴力却也有暴力的用处。在一个线程无时限sleep的时候也只有interrupt能够唤醒他。在interrupt的时候会抛出InterruptedException,这个Exception是由Thread 类自动抛出的。因此Interrupt带有强烈的阻塞味道。
wait与interrupt
interrupt同样可以打断wait的等待,与打断sleep不同的是,被打断的wait的线程在重新获得lock之前是不会抛出InterruptedException。
resume和suspend已经被Java遗弃,因为他们天生会引起线程的死锁。
suspend是个贪婪的家伙,当一个线程在suspend的时候,线程会停下来,但却仍然持有在这之前获得的锁定。其他线程无法使用他锁定的任何资源,除非这个挂起的线程被resume之后,他才会继续运行。对于线程的同步,使用wait与notify要安全的多。