Java并发之并行程序基础

实战Java高并发程序设计笔记


有关线程你必须知道的事

  1. 进程
    • 进程(Process)是计算机中程序关于某数据集合上的一次运行活动,事系统进行资源分配和调度的基本单位,是操作系统结构的基础。
  2. 线程的几个状态
  • 首先看Thread中的一个枚举State,线程共有六个状态,每个状态的含义注释讲的已经很清楚了
/**
     * A representation of a thread's state. A given thread may only be in one
     * state at a time.
     */
    public enum State {
        /**
         * The thread has been created, but has never been started.
         */
        NEW,
        /**
         * The thread may be run.
         */
        RUNNABLE,
        /**
         * The thread is blocked and waiting for a lock.
         */
        BLOCKED,
        /**
         * The thread is waiting.
         */
        WAITING,
        /**
         * The thread is waiting for a specified amount of time.
         */
        TIMED_WAITING,
        /**
         * The thread has been terminated.
         */
        TERMINATED
    }
  • 各状态间的关系如下图

    Java并发之并行程序基础_第1张图片
    线程状态图
  1. Thread的start( )方法和run( )方法的区别

    • run( )方法是一个普通的方法,调用该方法会在当前线程中串行执行run( )中的代码
    • start( )是个一个线程安全的方法,该方法首先会检查当前线程是否处于New状态, 然后将其加入到ThreadGroup中,最后调用Native start0( )方法,在新的线程中串行执行run( )中的代码
  2. 终止线程

  • 调用Thread.stop( )就会立即线程终止,方法太过暴力,可以强行把执行到一半的线程终止,例如如下代码
public class ThreadStop {
    public static void main(String arg[]) throws InterruptedException {
        Thread mThread = new StopThread() ;
        mThread.start();
        Thread.sleep(100);
        mThread.stop();//调用stop终止线程可导致run( )方法中的代码仅执行一部分
    }
static class StopThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100000; i++) {
                    System.out.println("i "+ i);
            }
        }
    }
}

可能得到如下结果,i的值并不等于99999
i 24956
i 24957
i 24958
i 24959
i 24960
i 24961
i 24962

  1. 线程中断
  • 线程中断时一种重要的线程协作机制。严格讲,线程中断并不会使线程立即退出,而是给线程发送一个通知,并告知目标线程,有人希望你退出!目标线接到通知后如何处理完全由目标线程自行决定。
  • 中断线程(Thread.interrupt( )),通知目标线程中断,也就是设置中断标志位
 public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();  
    }
  • 判断是否被中断(Thread.isInterrupted( ))
public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);
  • 判断是否被中断并清除当前中断状态
/**
     * Tests whether the current thread has been interrupted.  The
     * interrupted status of the thread is cleared by this method.  In
     * other words, if this method were to be called twice in succession, the
     * second call would return false (unless the current thread were
     * interrupted again, after the first call had cleared its interrupted
     * status and before the second call had examined it).
     *
     * 

A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return true if the current thread has been interrupted; * false otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { return currentThread().isInterrupted(true); }

  • 给出一断代码,显示线程中断,注意Thread.sleep( )方法会使当前线程休眠一段时间,若在此时线程接收到中断信号,sleep会抛出InterruptedException异常,并且会清除中断标志位。若不做处理,当前线程永远不会中断。
public class ThreadInterrupt {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new InterruptThread();
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
        Thread.sleep(4000);
    }
    static class InterruptThread extends Thread {
        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("Interrupted");
                    break;
                }
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    System.out.println("Interrupted when sleep");
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                Thread.yield();//让出当前CPU,然后跟其他线程竞争CPU的使用权
            }
        }
    }
}
  1. 等待( wait )和通知( notify )
public final native void wait() throws InterruptedException;
public final native void notify();
public final native void notifyAll();
  • wait 会使当前线程停止进入等待队列而转换为等待状态直到其他线程在同一个object调用notify或notifyAll
  • notify 会从等待队列中随机选择一个线程将唤醒
  • notifyAll 唤醒所有等待队列中的线程,等待线程就会去竞争资源
  • wait 和 sleep 都可以让线程等待一段时间,除了wait可以被唤醒外,wait 会释放目标对象的锁而sleep不会释放任何资源
  1. 挂起( suspend ) 和继续执行( resume )线程
  • suspend会导致线程暂停的同时并不会释放任何资源。如果其他任何线程想访问被他暂用的锁时都会那不会该所而进入等待状态。直到对应线程调用resume被挂机的线程才能继续执行,但是如果resume意外地在suspend前就调用了,那么被挂起的线程可能很难有机会继续呗执行
  1. 等待线程结束( join ) 和谦让( yield )
public final void join() throws InterruptedException
public final synchronized void join(long millis)
public static native void yield();
  • join( ) 表示无限等待,它会一直阻塞当前线程,直到目标线程执行完毕
  • oin(long millis) 参数的意思是等待目标线程的最大时间,如果超过时间目标线程还没有执行完毕那么当前线程就会继续执行下去
  • yield( )一旦调用,就会使当前线程让出CPU,然后可能会跟其他线程竞争CPU资源

你可能感兴趣的:(Java并发之并行程序基础)