并发学习笔记(3)

603 查看

虽是读书笔记,但是如转载请注明出处 http://segmentfault.com/blog/exploring/
.. 拒绝伸手复制党


Thread 线程的几种状态

线程具有新建、可运行、阻塞、等待、定时等待、死亡六种。线程的状态完全包含了一个线程从新建到运行,最后到结束的整个生命周期,

线程状态的具体信息如下:

NEW(新建状态、初始化状态):线程对象已经被创建,但是还没有被启动时的状态。这段时间就是在我们调用new命令之后,调用start()方法之前

    public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,      

RUNNABLE(可运行状态、就绪状态):在我们调用了线程的start()方法之后线程所处的状态。处于RUNNABLE状态的线程在JAVA虚拟机(JVM)上是运行着的,但是它可能还正在等待操作系统分配给它相应的运行资源以得以运行。

一旦一个线程开始运行,它不必始终保持运行。运行中的线程可能被中断,为了让其他线程获得运行机会 -- 线程调度。 现在所有的桌面和服务器OS都使用抢占式调用

 /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

BLOCKED(阻塞状态、被中断运行):当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态;当所有其他线程释放该锁,并且线程调度器要允许本线程持有它的时候,该线程将变成非阻塞状态。

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait} .
         */
        BLOCKED,

当线程等待另一个线程通知调度器的一个条件时,它自己进入等待状态。
当前线程调用了java.lang.Object.wait()java.lang.Thread.join()或者等待java.util.concurrent库中的LockCondition时,就会进入等待状态

比如一个线程调用了某个对象的wait()方法,正在等待其它线程调用这个对象的notify()或者notifyAll()(这两个方法同样是继承自Object类)方法来唤醒它;或者一个线程调用了另一个线程的join()(这个方法属于Thread类)方法,正在等待这个方法运行结束。

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li> {@link Object#wait() Object.wait} with no timeout </li>
         *   <li> {@link #join() Thread.join} with no timeout </li>
         *   <li> {@link LockSupport#park() LockSupport.park} </li>
         * </ul>
         *
         * <p> A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt> Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt> Object.notify()</tt> or <tt>Object.notifyAll() </tt> on
         * that object. A thread that has called <tt> Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

TIMED_WAITING(定时等待状态):当前线程调用了java.lang.Object.wait(long timeout)java.lang.Thread.join(long millis)java.util.concurrent.locks.LockSupport.packNanos(long nanos)java.util.concurrent.locks.LockSupport.packUntil(long deadline 四个方法中的任意一个,进入等待状态,但是与WAITING状态不同的是,它有一个最大等待时间,即使等待的条件仍然没有满足,只要到了这个时间它就会自动醒来。

         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li> {@link #sleep Thread.sleep}</li>
         *   <li> {@link Object#wait(long) Object.wait} with timeout</li>
         *   <li> {@link #join(long) Thread.join} with timeout </li>
         *   <li> {@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li> {@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

TERMINATED(死亡状态、终止状态):

  • 线程完成执行后的状态。线程执行完run()方法中的全部代码,从该方法中退出,进入TERMINATED状态。

  • 还有一种情况是run()在运行过程中抛出了一个异常,而这个异常没有被程序捕获,导致这个线程异常终止进入TERMINATED状态

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

线程的属性

线程的属性:线程优先级,守护线程,线程组以及处理未捕获异常的处理器。

线程优先级

java语言,每一个线程有一个优先级. 默认情况,一个线程继承它父线程的优先级。

可以用setPriority方法降低或提高任何线程的优先级。 使用yield()方法让当前执行的线程处于让步,如果有其他的runnable线程具有至少与此线程同样的优先级,那么这些线程接下来会被调度。

java   /**
     * The minimum priority that a thread can have.
     */
    public final static int MIN_PRIORITY = 1;

   /**
     * The default priority that is assigned to a thread.
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * The maximum priority that a thread can have.
     */
    public final static int MAX_PRIORITY = 10;

守护线程

可以通过调用

t.setDaemon(true);

将线程转换为守护线程。守护线程唯一的用途就是为其他线程服务。
计时线程就是一个守护线程:它定时地发送“计时器滴答”信号给其他线程或清空过时的高速缓存项的线程。

当只剩下守护线程,JVM就退出了。守护线程不应该去访问任何固有资源,如文件,数据库,因为它会在任何时候甚至在一个操作中发生中断。

未捕获异常处理器

线程run方法不能跑出任何被检测的异常,但是不被检测的异常会导致线程终止,这种情况,线程就死亡了。