线程

线程

#创建线程的方式

  • 方法一
extends Thread
  • 方法二
implements Runnable
  • 方法三
implements Callable<T>
  • 方法三

    线程池

    • Executors.newFixedThreadPool();
    • Executors.newSingleThreadExecutor();
    • Executors.newCachedThreadPool();
    • Executors.newScheduledThreadPool();

    一般需要手动创建线程池

    ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
                                                         maximumPoolSize, 
                                                         keepAliveTime, 				                                                        unit,
                                                         workQueue,
                                                         Executors.defaultThreadFactory(), 
                                                         defaultHandler)
    

    参数说明

    • coolPoolSize 核心线程数

      当前线程池中空闲的线程数, 运行时该线程始终不会被销毁, 要小于maximumCoreSize

    • maximumCoreSize

      线程池能创建的最大线程, 当WorkQueue的队列存储的任务满了, 且当前正在运行的线程数

      小于maximumCorseSize时, 就会创建一个线程来运行不在WorkQueue中的任务, 一般设置

      为一般设置为比Runtime.getRuntime().availableProcessors()大1或2

    • keepAliveTime

      如果当前线程数大于corePoolSize时且有线程空闲时间大于keepAliveTime时, 销毁线程数至corePoolSize

    • unit

      keepAliveTime的时间单位

    • workQueue阻塞队列

      一般采用LinkedBlockingQueue, 默认是无边界的, 必须要指定大小

    • threadFactory

      用于自定义线程的名字

    • handler

      拒绝策略, 当当正在运行的线程等于maximumPoolSize且大于workQueue队列满了,就会采取handler

      • new ThreadPoolExecutor.AbortPolicy()

        线程池默认采用该模式handler

        如果任务数超出队列与最大线程数的值时抛出异常

      • new ThreadPoolExecutor.DiscardPolicy()

        抛弃溢出的任务

      • new ThreadPoolExecutor.DiscardOldestPolicy()

        线程满了且超过阻塞队列容乃,移除队列头,将新任务放入队列末尾

#线程的状态

NEW , RUNNABLE , BLOCKED , WAITING, TIMED_WAITING, TERMINATED

#sleep()与 wait()的区别

sleep()报锁睡眠, wait()阻塞时释放锁

#Synchronize

重锁/ 同步锁/ 悲观锁/ 互斥锁

  • 一个线程调用了锁方法后,其他线程不能进入该类访问任一一个锁方法

  • 访问的对象不是同一个,不会阻塞

  • 访问对象非同步方法,不会阻塞

  • 访问锁的类型不同,不会阻塞

#终止线程的方式

  • semaphore 信号量,标志位

  • stop()过时, 有可能造成死锁

  • interrupt(), 通过isInterrupted()判断

#volatile

  • 可见性

    保证了当数据重新写回主存时数据,所有线程可见

  • 有序性 (写在读之前)

    对一个volatile域的写,happens-before于后续对这个volatile域的读

  • 原子性 !!!注意volatile不具有原子性

    保证操作不分隔

    例如:

    i++ 不具备原子性

    分为三步

    1. 从主存中读取i

    2. i+1

    3. 将数据写回主存

    所以操作++时要上锁或是使用Atomic相关类, 凡是读写操作都不具有原子性

#ThreadLocal

每个线程中都有一个自己的 ThreadLocalMap 类对象,可以将线程自己的对象保持到其中,
各管各的,线程可以正确的访问到自己的对象。

#JMM

posted @ 2020-07-15 21:54  CyberPelican  阅读(92)  评论(0编辑  收藏  举报