1新建(new)
2可运行(Ruannable).start
3阻塞状态( BLOCKED ) :可运行状态遇到了锁
4.等待状态(WAITING):遇到了wait方法
5.计时等待( TIMED_WAITING):遇到了sleep方法
6.死亡状态( TERMINATED):进程结束变成垃圾
存放线程的容器
创建一个线程池,里面是空的,当有任务需要执行时,才会创建线程对象,当对象执行完毕时,线程对象归还给线程池
避免为了频繁创建线程造成资源浪费,可以提高体统的效率
自动创建(不推荐): Executors new ThreadPoolExecutor
使用Executors中所提供的静态方法来创建线程池
static ExecutorService newCachedThreadPool() 创建一个默认的线程池 ? static ExecutorService newFixedThreadPool(int nThreads) 创建一个指定最多线程数量的线程池
手动创建: ThreadPoolExecutor (七个参数)
参数一:核心线程的数目 不能小于0
参数二:最大线程数目 不能小于0 最大数目>=核心线程数
参数三:空闲线程的最大存活时间 不能小于0
参数四:空闲线程的最大存活时间单位 不能为null
参数五:任务队列(一般使用ArrayBlockingQueue)因为有限制线程数量 不能为null
参数六:创建线程工厂 不能为null
参数七:拒绝策略 不能为null
参数一:核心线程数量,线程池中初始线程数,刚刚创建ThreadPoolExecutor的时候,线程并不会立即启动,而是要等到有任务提交时才会启动 当线程数超过核心线程数时,会将请求的任务放入任务队列 参数二:最大线程数,当任务队列满时,如果线程数没有超过最大线程数时,创建新的线程 参数三:空闲线程最大存活时间 参数四:时间单位---TimeUnit 参数五:任务队列 --- 当线程数超过核心线程数量小于最大线程数时,让任务在队列中等着,等有线程空闲了,再从这个队列中获取任务并执行 参数六:创建线程工厂 --- 按照默认的方式创建线程对象 参数七:任务的拒绝策略 --- 1.什么时拒绝? 当提交的任务 > 池子中最大的线程数量+队列的容量 //2.如何拒绝? 拒绝策略
可见性:多个线程同时访问一个共享变量时,其中一个线程对静态变量进行修改,其他进程能够立刻获得修改后的值(volatiel关键字或者上锁可以解决)
原子性:操作是不能中断的,线程要不全部执行成功,要不全部执行失败()
有序性:编译器和处理器为了优化性能而对指令序列进行重新排序,就是编写的代码执行的顺序和编写的不一致
1.除了long和double以外的全部基本数据类型(long和double因为字节数都是64位,以前的计算机都是32位,需要合并)
2.volatiel变量的赋值
3.java.concurrent.Atomic *类的所有操作
java内存模型是一种虚拟的存在,并不是真实存在的,它描述的是一种规范或者规则,通过这种规则定义了程序中的共享变量(包括实例(对象)字段,静态字段和构成数组对象的元素)的访问方式
JMM就是JAVA内存模型,JMM规定1.每个线程中操作共享变量都只能在自己的工作内存中操作,不能再主存中直接读写 2.不同线程不能直接访问其他线程工作内存中的变量,线程中变量值的传递只能通过主存进行。(可以对比CPU->Cache->内存)
synchronized :1.线程加锁时,将清除线程工作内存中共享变量的数据,直接从主存中读取数据进程操作 2.线程释放锁时,将共享变量的最新值存储到主存中
volatile:线程写数据的时候,JMM会把共享变量的最新值存到主存中,线程读数据的时候,JMM会把线程中的工作内存中的共享变量制为无效,并把主存中的最新值赋给线程中的工作内存。 ?
synchronized
CAS
1.什么是原子操作类?
原子操作类提供了一种用法简单,性高效,线程安全的更新一个变量的方式(原子基本数据类型,原子更新数组,原子更新引用,原子更新属性(字段))
2.如何使用原子的方式更新基本类型?
AtomicBoolean: 原子更新布尔类型
AtomicInteger: 原子更新整型
AtomicLong: 原子更新长整型
3.AtomicInteger的常用方法:
方法 | 说明 |
---|---|
public AtomicInteger() | 初始化一个默认值为0的原子型Integer |
public AtomicInteger(int initialValue) | 初始化一个指定值的原子型Integer |
int get() | 获取值 |
int getAndIncrement() | 以原子方式将当前值加1,注意,这里返回的是自增前的值。 |
int incrementAndGet() | 以原子方式将当前值加1,注意,这里返回的是自增后的值。 |
int addAndGet(int data) | 以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果 |
int getAndSet(int value) | 以原子方式设置为newValue的值,并返回旧值 |
代码实现 :
1.Hashtable :HashMap的线程是不安全的,为了保证数据的安全性,但是效率比较低
1.Hashtable的特点:1.采用悲观锁synchronized保证数据安全 2.只要有线程访问,会把整个表锁起来
2.1ConcurrentHashMap:保证线程的安全性和效率
让一条线程等待,等别的线程都结束在执行
原理:
CountDownLatch是通过一个计数器来实现的,计数器的初始值为需要等待线程的数量。
eg:CountDownLatch c = new CountDownLatch(10); // 等待线程的数量为10
线程调用CountDownLatch的await()方法会阻塞当前线程(即:主线程在闭锁上等待),直到计数器的值为0。
当一个工作线程完成了自己的任务后,调用CountDownLatch的countDown()方法,计数器的值就会减1。
当计数器值为0时,说明所有的工作线程都执行完了,此时,在闭锁上等待的主线程就可以恢复执行任务
可以控制资源的访问线程数量
原理:
Semaphore是通过一个计数器(记录许可证的数量)来实现的,计数器的初始值为需要等待线程的数量
eg:Semaphore s = new Semaphore(10); // 线程最大的并发数为10
线程通过acquire()方法获取许可证(计数器的值减1),只有获取到许可证才可以继续执行下去,否则阻塞当前线程
原文:https://www.cnblogs.com/zhangmeng0726/p/14623306.html