1. 什么是JUC
1.1 JUC 简介
在Java 中,线程部分是一个重点,本篇文章说的JUC 也是关于线程的。JUC就是java.util
.concurrent 工具包的简称。这是一个处理线程的工具包,JDK1.5 开始出现的。
1.2 线程和进程概念
1.2.1 进程与线程
1.2.1.1 进程(Process)
是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单
位,是操作系统结构的基础。
在当代面向线程设计的计算机结构中,进程是线程的容器。
程序是指令、数据及其组织形式的描述,进程是程序的实体。
是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单
位,是操作系统结构的基础。
程序是指令、数据及其组织形式的描述,进程是程序的实体。
1.2.1.2 线程(thread )
是操作系统能够进行运算调度的最小单位。
它被包含在进程之中,是进程中的实际运作单位。
一条线程指的是进程中一个单一顺序的控制流一个进程中可以并发多个线程,每条线程并行执
行不同的任务。
1.2.1.3 总结来说:
进程
指在系统中正在运行的一个应用程序
程序一旦运行就是进程
进程一一资源分配的最小单位。
线程
系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。
线程一一程序执行的最小单位。
1.3 线程的状态
1.3.1 线程状态枚举类
Thread.State
NEW
A thread that has not yet started is in this state.
RUNNABLE
A thread executing in the Java virtual machine is in this state.
BLOCKED
A thread that is blocked waiting for a monitor lock is in this state.
WAITING
A thread that is waiting indefinitely for another thread to perform a particular
action is in this state.
TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a
specified waiting time is in this state.
TERMINATED
A thread that has exited is in this state.
public enum State {
/**
* Thread state for a thread which has not yet started.
* 新建
*/
NEW,
/**
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,
1.3.3 wait/sleep的区别
sleep 是 Thread 的静态方法。wait 是 Object 的方法,任何对象实例都能调用。
sleep 不会释放锁,它也不需要占用锁。wait 会释放锁,但调用它的前提是当前线程占有锁(即
代码要在 synchronized 中)。
它们都可以被 interrupted 方法中断。
1.4 并发和并行
/**
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 Object.wait.
阻塞
*/
BLOCKED,
/**
Thread state for a waiting thread. A thread is in the waiting state due to
calling one of the following methods:
Object.wait with no timeout
Thread.join with no timeout
LockSupport.park
A thread in the waiting state is waiting for another thread to perform a
particular action. For example, a thread that has called Object.wait() on an
object is waiting for another thread to call Object.notify() or
Object.notifyAll() on that object. A thread that has called Thread.join() is
waiting for a specified thread to terminate.
等待
*/
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:
Thread.sleep
Object.wait with timeout
Thread.join with timeout
LockSupport.parkNanos
LockSupport.parkUntil
超时等待
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
* 结束
*/
TERMINATED;
}
1.4.1串行模式
串行表示所有任务都一一按先后顺序进行。串行意味着必须先装完一车柴才能运送这车柴,只有运
送到了,才能卸下这车柴,并且只有完成了这整个三个步骤,才能进行下一个步骤。
串行是一次只能取得一个任务,并执行这个任务
1.4.2 并行模式
并行意味着可以同时取得多个任务,并同时去执行所取得的这些任务。并行模式相当于将长长的
一条队列,划分成了多条短队列,所以并行缩短了任务队列
的长度。并行的效率从代码层次上强依赖于多进程/多线程代码,从硬件角度上则依赖于多核 CPU。
并发:同一时刻多个线程在访问同一个资源,多个线程对一个点
例子 : 春运抢票 电商秒杀...
并行:多项工作一起执行,之后再汇总
例子:泡方便面,电水壶烧水,一边撕调料倒入桶中
1.5 管程
Monitor 监视器 所说锁
是一种同步机制,保证同一个时间,只有一个线程访问被保护数据或者代码
jvm同步基于进入和退出,使用管程对象实现的
1.6 用户线程/守护线程
2. Lock
2.1 复习Synchronized
2.1.1 Synchronized 关键字回顾
synchronized 是 Java 中的关键字,是一种同步锁。它修饰的对象有以下几种 :
修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,
作用的对象是调用这个代码块的对象;
修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这
个方法的对象;
虽然可以使用 synchronized 来定义方法,但 synchronized 并不属于方法定义的一
部分,因此,synchronized 关键字不能被继承。
如果在父类中的某个方法使用了 synchronized 关键字,而在子类中覆盖了这个方
法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法
中加上synchronized 关键字才可以。
当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步
的,但子类调用了父类的同步方法,因此子类的方法也就相当于同步了。
修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象
修饰一个类,其作用的范围是 synchronized 后面括号括起来的部分,作用主的对象是这个类
的所有对象。
2.2 什么是 Lock
Lock 锁实现提供了比使用同步方法和语句可以获得的更广泛的锁操作。它们允许更灵活的结构,可
能具有非常不同的属性,并且可能支持多个关联的条件对象。Lock 提供了比 synchronized 更多的功
能。
Lock 与的 Synchronized 区别
Lock 不是 Java 语言内置的,synchronized 是Java 语言的关键字,因此是内置特性。
Lock 是一个类,通过这个类可以实现同步访问;
Lock 和 synchronized 有一点非常大的不同,采用 synchronized 不需要用户去手动释放锁,
当 synchronized 方法或者 synchronized 代码块执行完之后系统会自动让线程释放对锁的占
用;
而 Lock 则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
Lock 和 synchronized 有以下几点不同:
1. Lock 是一个接口,而 synchronized 是Java 中的关键字,synchronized 是内置的语言实现 ;
2. synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock
在发生异常时,如果没有主动通过 unLock0去释放锁,则很可能造成死锁现象,因此使用
Lock 时需要在 finally 块中释放锁;
3. Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用synchronized 时,等待
的线程会一直等待下去,不能够响应中断 ;
4. 通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
5. Lock 可以提高多个线程进行读操作的效率。
在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量
线程同时竞争),此时 Lock 的性能要远远优于synchronized。
3.线程间通信
3.1 多线程编程步骤