一、進(jìn)程與線程
1.1 進(jìn)程
進(jìn)程: 是程序的一次動態(tài)執(zhí)行麸拄,它對應(yīng)著從代碼加載派昧,執(zhí)行至執(zhí)行完畢的一個完整的過程,是一個動態(tài)的實(shí)體感帅,它有自己的生命周期斗锭。它因創(chuàng)建而產(chǎn)生,因調(diào)度而運(yùn)行失球,因等待資源或事件而被處于等待狀態(tài)岖是,因完成任務(wù)而被撤消帮毁。反映了一個程序在一定的數(shù)據(jù) 集上運(yùn)行的全部動態(tài)過程。通過進(jìn)程控制塊(PCB)唯一的標(biāo)識某個進(jìn)程豺撑。同時進(jìn)程占據(jù)著相應(yīng)的資源(例如包括cpu的使用 烈疚,輪轉(zhuǎn)時間以及一些其它設(shè)備的權(quán)限)。
是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個獨(dú)立單位聪轿。
1.2 線程
一個進(jìn)程可以分為一到多個線程
一個線程就是一個指令流爷肝,將指令流中的一條條指令以一定的順序交給CPU執(zhí)行。
JAVA中陆错,線程作為最小的調(diào)度單位灯抛,進(jìn)程作為資源分配的最小單位。在windows中進(jìn)程是不活動的音瓷,只是作為線程的容器对嚼。
1.3 進(jìn)程和線程對比
二、并行和并發(fā)绳慎、同步和異步纵竖、阻塞和非阻塞
2.1 并行和并發(fā)
并發(fā):一個處理器可以同時處理多個任務(wù)。這是邏輯上的同時發(fā)生杏愤。
即:同一時間可以應(yīng)對多個任務(wù)的能力靡砌。
并行:多個處理器同時處理多個不同的任務(wù)。這是物理上的同時發(fā)生珊楼。
即:同一時間可以同時做多個任務(wù)的能力通殃。
有一個清晰地比喻:
并發(fā):一個人同時吃三個蘋果。并行:三個人同時吃三個蘋果亥曹。
-
并發(fā)(concurrency)
-
并行(parallel)
2.2 邓了、同步和異步
同步:需要等待結(jié)果返回,才能繼續(xù)運(yùn)行媳瞪。
異步:無需等待結(jié)果返回骗炉,就能繼續(xù)運(yùn)行。
同步就是燒開水蛇受,需要自己去輪詢(每隔一段時間去看看水開了沒)句葵,異步就是水開了,然后水壺會通知你水已經(jīng)開了兢仰,你可以回來處理這些開水了乍丈。
同步和異步是相對于操作結(jié)果來說,會不會等待結(jié)果返回把将。
2.3轻专、阻塞和非阻塞
阻塞就是線程在執(zhí)行過程中不可以做其它的事情,非阻塞就是線程在執(zhí)行中可以做其它的事情察蹲。
阻塞舉例
順序開會请垛,一場會開完才能開另一場會催训。非阻塞舉例
一邊打印文件一邊聽歌。
三宗收、通過繼承Thread或?qū)崿F(xiàn)Runnable 接口創(chuàng)建線程
3.1 直接重寫Thread的run 方法
- demo01 創(chuàng)建Thread
@Slf4j
public class CreateThread {
public static void main(String[] args) {
method01();
method02();
log.info("thread is running");
}
public static void method01(){
Thread thread = new Thread(){
@Override
public void run(){
log.info(" running");
}
};
thread.setName("th01");
thread.start();
}
public static void method02(){
Thread thread = new Thread(() -> log.info(" running"));
thread.setName("th02");
thread.start();
}
}
3.2 自定義類實(shí)現(xiàn)實(shí)現(xiàn)Runnable 接口
@Slf4j
public class JeffRunnable implements Runnable {
private int ticket = 5;
@Override
public void run() {
while (true) {
log.info("Thread ticket = {}", ticket--);
if (ticket < 0) {
break;
}
}
log.info("my thread is running");
}
public static void main(String[] args) {
JeffRunnable myThread = new JeffRunnable();
Thread thread01 = new Thread(myThread);
Thread thread02 = new Thread(myThread);
thread01.setName("my thread 01");
thread02.setName("my thread 02");
thread01.start();
thread02.start();
}
}
00:10:07.666 [my thread 01] INFO com.learn.thread.learn01.MyThread - Thread ticket = 5
00:10:07.666 [my thread 02] INFO com.learn.thread.learn01.MyThread - Thread ticket = 4
00:10:07.679 [my thread 02] INFO com.learn.thread.learn01.MyThread - Thread ticket = 2
00:10:07.679 [my thread 01] INFO com.learn.thread.learn01.MyThread - Thread ticket = 3
00:10:07.679 [my thread 02] INFO com.learn.thread.learn01.MyThread - Thread ticket = 1
00:10:07.679 [my thread 01] INFO com.learn.thread.learn01.MyThread - Thread ticket = 0
00:10:07.679 [my thread 01] INFO com.learn.thread.learn01.MyThread - my thread is running
00:10:07.679 [my thread 02] INFO com.learn.thread.learn01.MyThread - my thread is running
3.3 Thread 和 Runnable接口的關(guān)系
Thread有單繼承的問題漫拭;
Thread 本身也是實(shí)現(xiàn)了Runnable接口
public
class Thread implements Runnable {
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
private volatile String name;
private int priority;
private Thread threadQ;
private long eetop;
四、通過Callable混稽、Future和FutureTask 創(chuàng)建線程
4.1 Callable
- Callable 是一個接口采驻,含有一個帶返回值的call 方法
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
4.2 Future
Future就是對于具體的Runnable或者Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢是否完成匈勋、獲取結(jié)果礼旅。必要時可以通過get方法獲取執(zhí)行結(jié)果,該方法會阻塞直到任務(wù)返回結(jié)果洽洁。
- Future 也是一個接口各淀,定義了6個方法
public interface Future<V> {
//方法用來取消任務(wù)
boolean cancel(boolean mayInterruptIfRunning);
//方法表示任務(wù)是否被取消成功
boolean isCancelled();
// 方法表示任務(wù)是否已經(jīng)完成
boolean isDone();
// 方法用來獲取執(zhí)行結(jié)果,這個方法會產(chǎn)生阻塞诡挂,會一直等到任務(wù)執(zhí)行完畢才返回;
V get() throws InterruptedException, ExecutionException;
//用來獲取執(zhí)行結(jié)果临谱,如果在指定時間內(nèi)璃俗,還沒獲取到結(jié)果,就直接返回null悉默。
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
也就是說Future提供了三種功能:
1)判斷任務(wù)是否完成城豁;
2)能夠中斷任務(wù);
3)能夠獲取任務(wù)執(zhí)行結(jié)果抄课。
因?yàn)镕uture只是一個接口唱星,所以是無法直接用來創(chuàng)建對象使用的,因此就有了下面的FutureTask跟磨。
4.3 FutureTask
FutureTask 通過 RunnableFuture 間接實(shí)現(xiàn)了Runnable 和 Future
public class FutureTask<V> implements RunnableFuture<V> {
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
- FutureTask 兩個構(gòu)造函數(shù)间聊,既可以處理callable,又可以處理runnable
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
4.4 代碼示例
@Slf4j
public class JeffCallable implements Callable<Integer> {
private int ticket = 5;
@Override
public Integer call() {
ticket--;
log.info("Thread ticket = {}", ticket);
return ticket;
}
public static void main(String[] args) {
//創(chuàng)建callable對象
JeffCallable call=new JeffCallable();
FutureTask<Integer> futureTask=new FutureTask<Integer>(call);
Thread thread=new Thread(futureTask,"th01");
thread.start();
//得到返回值
try {
log.info("返回值是:{}", futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}