用于表示多个操做“依次处理”。好比把十个操做交给一我的来处理时,这我的要一个一个地按顺序来处理java
用于标识多个操做“同时处理”。好比十个操做分给两我的处理时,这两我的就会并行来处理。设计模式
相对于顺序和并行来讲比较抽象,用于表示“将一个操做分割成多个部分而且容许无序处理”。好比将十个操做分红相对独立的两类,这样便可以开始并发处理了。若是一我的来处理,这我的就是顺序处理分开的并发操做,而若是是两我的,这两我的就能够并行处理同一个操做。多线程
多线程程序都是并发处理的。若是 CPU 只有一个,那么并发处理就是顺序执行的,而若是有多个 CPU,那么并发处理就可能会并行运行。并发
并发处理的顺序执行与并发处理的并行执行示意图以下所示 this
Thread
类的子类的实例启动线程Runnable
接口的实现类的实例启动线程以上两种方式都须要使用 start 方法用于启动新的线程,在此须要注意的事情是,启动新线程调用的是 start 方法而不是 run 方法url
直到全部的线程都终止后,程序才会终止。也就是说,当这两个线程都终止后,程序才会终止。spa
Java 程序的终止是指除守护线程之外的线程所有终止。守护线程是执行后台做业的线程。咱们能够经过
setDaemon
方法把线程设置为守护线程。线程
java.util.concurrent 包中包含一个将线程建立抽象化的 ThreadFactory 接口。利用该接口,咱们能够将 Runnable 做为传入参数并经过 new 建立 Thread 实例的处理隐藏在 ThreadFactory 内部。设计
Executors 类中含有多种建立 ThreadFactory 的方法,感兴趣的能够去看一下源码code
若是声明一个方法时,在前面加上关键字 synchronized 那么这个方法就只能由一个线程运行。只能由一个线程运行是每次只能由一个线程运行的意思,并非说仅能让某一特定线程运行。这种方法叫作 synchronized,有时也称为同步方法。
synchronized void method() {
...
}
复制代码
若是只是想让方法中的某一部分由一个线程运行,而非整个方法,则可以使用 synchronized 代码块
synchronized (表达式) {
...
}
复制代码
假设有以下 synchronized 实例方法
synchronized void method() {
...
}
复制代码
这跟下面将方法体用 synchronized 代码块包围起来是等效的
void method() {
synchronized (this) {
...
}
}
复制代码
synchronized 实例方法是使用 this 的锁来执行线程的互斥处理的
synchronized 静态方法和 synchronized 实例方法是相同的。可是 synchronized 静态方法使用的锁和 synchronized 实例方法使用的锁是不同的
class Something {
static synchronized void method() {
...
}
}
复制代码
这跟下面将方法体用 synchronized 代码块包围起来是等效的
class Something {
static void method() {
synchronized (Something.class) {
...
}
}
}
复制代码
synchronized 静态方法是使用该类的类对象锁来执行线程的互斥处理的。 Something.class 是 Something 类对应的 java.lang.class 类的实例
全部实例都拥有一个等待队列,它是在实例的 wait 方法执行后中止操做的线程队列。就比如为每一个实例准备的线程休息室
在执行 wait 方法后,线程便会暂停操做,进入等待队列这个休息室。除非发生下列某一状况,不然线程会一直在等待队列中休眠。
若要执行 wait 方法,线程必须持有锁。但若是线程进入等待队列,便会释放其实例的锁
该方法会将等待队列中的一个线程去除。同 wait 方法同样,若要执行 notify 方法,线程也必须持有要调用的实例的锁。
notify 唤醒的线程并不会在执行 notify 的一瞬间就从新运行。由于在执行 notify 的那一瞬间,执行 notify 的线程还持有着锁,因此其余线程还没法获取这个实例的锁
notify 方法仅唤醒一个线程,而 notifyAll 则唤醒全部线程,这是二者之间惟一的区别
同 wait 方法和 notify 方法同样, notifyAll 方法也只能由持有要调用的实例锁的线程调用
notify 方法和 notifyAll 方法很是类似,到底该使用哪一个?
实际上,这很难选择,因为 notify 唤醒的线程较少,因此处理速度要比使用 notifyAll 时快。 但使用 notify 时,若是处理很差,程序即可能会中止。通常来讲,使用 notifyAll 时的代码要比使用 notify 时的更为健壮。