3.Java 并发编程基础

3.Java 并发编程基础

3.1 线程简介

3.1.1 什么是线程

现代操作系统的最小调度单位。

3.1.2 为什么使用多线程

  • 更多的处理核心
  • 更快的响应时间
  • 更好的编程模型

3.1.3 线程的优先级(没什么用)

3.1.4 线程的状态

  • NEW
  • RUNNABLE
  • BLOCKED
  • WAITING
  • TIMED_WAITING
  • TERMINATED

3.1.5 线程状态的变换

  • NEW -> RUNNABLE
    • Thread.start()
  • RUNNABLE -> TERMINATED
    • 执行完成
  • RUNNABLE -> TIMED_WAITING
    • Thread.sleep()
    • Object.wait()
    • Thread.join()
    • LockSupport.parkNanos()
    • LockSupport.parkUtil()
  • RUNNABLE -> TIMED_WAITING
    • Object.notify()
    • Object.notifyAll()
    • LockSupport.unpark(Thread)
    • 超时时间到
  • RUNNABLE -> BLOCKED
    • 等待进入synchronized方法
    • 等待进入synchronized块
  • BLOCKED -> RUNNABLE
    • 获取到锁
  • RUNNABLE -> WAITING
    • Object.join()
    • Object.wait()
    • LockSupport.park()
  • WAITING -> RUNNABLE
    • Object.notify()
    • Object.notifyAll()
    • LockSupport.unpark(Thread)

3.1.6 Daemon线程

主要用于程序中后台调度。
JVM中不存在非Daemon线程,将会退出。

3.2 启动和终止线程

3.2.1 构造线程

新构造的线程对象是由其parent线程来进行空间分配的。

3.2.2 启动线程

线程对象在初始化完成后,调用start()方法就可以启动。

3.2.3 中断

  • 中断是线程的一个标志属性,表示一个运行中的线程是否被其他线程终端。
  • 其他线程调用该线程的interrupt()方法对其进行中断。
  • 线程通过isInterrupted()判断是否被中断
  • Thread.interrupted() 对当前线程的中断标示位进行复位。
  • 抛出InterruptedException的线程,其中断位会被清除。

3.2.4 过时的suspend,resume,stop

  • suspend 不会释放已有资源,而是占有资源进入睡眠
  • stop 不会释放资源

3.2.5 安全的终止线程

通过标志位或者interrupted 终止线程。

3.3 线程间通信

3.3.1 volatile 和 synchronized

volatile 修饰变量表示程序对该变量的获取必须从内存中获取,对该变量的修改必须刷回到内存中。

synchronized 修饰,保证多个线程,只有一个在同步方法块中。

3.3.2 等待 通知

线程A调用对象O的wait()进入等待状态,线程B调用对象O的notify()或者notifyAll(),线程A收到通知后,从对象O的wait()中返回,进行后续操作。

使用细节:

  • 使用wait notify notifyAll 要先对对象O加锁
  • 调用wait 方法后,线程从RUNNING变为WAITING,并将线程放入对象O的等待队列中
  • notify notifyAll 调用之后,等待线程A在调用notify notifyAll线程B释放锁之后,A才有机会从wait 返回
  • notify 将等待队列中的一个等待线程移动到同步队列,notifyAll将所有线程移动,被移动的从WAITING变为BLOCKED
  • 要从wait中返回,必须持有对象的锁。

3.3.3 管道输入/输出流

管道使用内存用于线程之间的数据传输。
包括四种具体的实现:

  • PipedOutputStream 面向字节
  • PipedInputStream 面向字节
  • PipedReader 面向字符
  • PipedWriter 面向字符

使用的时候,输入输出流要绑定在一起。

3.3.4 Thread.join

线程A执行thread.join(), 意味着线程A等待线程thread终止之后,才从thread.join()返回。

public class Join {

    public static void main(String[] args) throws Exception {
        Thread previous = Thread.currentThread();

        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new Domino(previous), String.valueOf(i));
            thread.start();
            previous = thread;
        }
        TimeUnit.SECONDS.sleep(5);
        System.out.println(Thread.currentThread().getName() + "terminate");
    }

    static  class Domino implements Runnable{
        private Thread thread;

        public Domino(Thread thread) {
            this.thread = thread;
        }

        @Override
        public void run() {
            try {
                thread.join();
            } catch (InterruptedException e){

            }
            System.out.println(Thread.currentThread().getName() + " terminate");
        }
    }
}

  • join(long millis)
  • join(long millis, int nanos)
    这两个有超时机制,超过一定时间之后,会从thread.join()返回。

原理:

public final synchronized void join() throws InterruptedException {
    
    // 若thread 存活,等待被notify 或者notifyAll
    while(isAlive()){
        wait(0);
    }
}
  • 线程A调用thread.join()一直在等待thread的锁.
  • thread 终止后,调用notifyAll()
  • 线程A获得锁,执行 join()方法

3.3.5 ThreadLocal

ThreadLocal 是线程变量,k-v 结构,k为ThreadLocal对象,值为任意对象。一个线程可以根据ThreadLocal对象查询到绑定在该线程上的变量的值。

public class Profile {

    private static final ThreadLocal<Long> TIME_THREADLOCAL = new ThreadLocal<Long>(){
        protected Long initalValue(){
            return System.currentTimeMillis();
        }
    };


    public static final void begin(){
        TIME_THREADLOCAL.set(System.currentTimeMillis());
    }

    public static final Long end(){
        return System.currentTimeMillis() - TIME_THREADLOCAL.get();
    }

    public static void main(String[] args) throws Exception{
        Profile.begin();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Cost: " + Profile.end());
    }

    
}

猜你喜欢

转载自blog.csdn.net/huatangzhithree/article/details/89913573
今日推荐