原文鏈接:併發編程<多線程基礎一>
2020-04-16 11:12 晴🌤
**併發編程,必須會基礎點整理**
/**
* 線程基礎:
* Created by 李澤陽 on 2020/4/15 10:20
*/
public class ThreadBasics {
/**
* 1、進程和線程的區別?
* 答:進程是操作系統調度的最小單位,線程是cpu調度的最小調度單位
* 線程共享進程的資源,例如:迅雷下載電影。。。OS限制:Linux(max)1000個,Windows(max)2000個,線程
* 好處:充分利用cpu資源,單線程下載其他全部等待,模塊化,異步化。
* <p>
* 2、cpu核心數和線程數的關係?
* 答:os的超線程技術,1:2
* <p>
* 3、cpu時間片輪轉機制?
* 答:給每個線程分配時間片段,上下文切換,代價大:2w個cpu的週期(編寫代碼儘量避免)
* <p>
* 4、並行和併發?
* 答:併發(單位時間內的併發量),應用併發交替使用
* 並行(同時執行)
* <p>
* 5、線程的兩種啓動方式,Thread、runnable的區別?
* 答:Thread是線程的抽象,runnable是具體任務的抽象
* <p>
* 6、線程的stop()強制終止爲什麼不建議使用?
* 答:因爲它的終止方式非常的野蠻,直接關閉,可能導致線程佔用的鎖資源不釋放,形成死鎖。
* <p>
* 7、線程run()和start()的區別?
* 答:run(),普通方法多次調用,start()單次調用,線程就緒真正啓動線程。
* run(),主線程調用不啓動子線程,start(),啓動子線程
* <p>
* 8、內置鎖的對象必須保持不變 Integer 爲啥不行?
* 答:Integer在每次返回的時候,都會創建new新的對象。
* <p>
* 9、爲何不建議使用自定義中斷?而使用interrupt()
* 答:自定義中斷,裏面進行wait(),或者進行休眠,不滿做條件不會出來,不會中斷。
* 而,jdk的sleep、wait 等線程繼承了中斷異常
* <p>
* 10、守護線程setDaemon(true);run()裏面的finally一定執行嗎?
* 答:不一定執行,守護線程隨着主線程關閉而關閉。
* <p>
* 11、對象鎖,類鎖,synchronized?是什麼
* 答:共有對象進行加鎖,類鎖是static的方法上枷鎖,是實例創建的類鎖。
*/
//線程的實現方式,extends Thread
public static class UsThread extends Thread {
String threadName = Thread.currentThread().getName();
Object obj = new Object();//內置鎖,鎖對象用的
Integer integer;
/**
* integer valueOf源碼
* public static Integer valueOf(int i) {
* if (i >= IntegerCache.low && i <= IntegerCache.high)
* return IntegerCache.cache[i + (-IntegerCache.low)];
* return new Integer(i);
* }
*/
private static boolean isStop = false;//自定義中斷,錯誤使用方法
public static boolean isIsStop() {
return isStop;
}
public static void setIsStop(boolean isStop) {
UsThread.isStop = isStop;
}
@Override
public void run() {
//synchronized (integer) {//創建新的對象
synchronized (obj) {//鎖對象,必須保持不變
while (!isInterrupted()) {//檢查中斷標識位
/* while (isStop) {
//錯誤使用方法,自定義boolean,錯誤的
try {
//等待,或者,休眠,不會感知自定義的中斷位------9
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/
System.out.println(threadName);
}
}
}
}
//線程的實現方式,implements Runnable
public static class UsRunnable implements Runnable {
String threadName = Thread.currentThread().getName();
@Override
public void run() {
/**
* 線程的其他操作方法
* 1、讓出線程,讓出cpu的時間片段,不讓其他資源
* 2、睡眠線程
* 3、等待線程
* 4、加入線程
* 5、守護線程,隨着主線程進行
*/
try {
Thread.yield();//讓出線程
Thread.sleep(100);//線程的睡眠
} catch (InterruptedException e) {
e.printStackTrace();
}
//獲取當前線程進行中斷
while (Thread.currentThread().isInterrupted()) {
System.out.println(threadName);
}
}
}
//類鎖,
public synchronized void te_Syn() {
synchronized (this) {//對象鎖
System.out.println("");
}
}
public static void main(String[] args) {
UsThread t1 = new UsThread();
t1.start();//方式一
UsRunnable usRunnable = new UsRunnable();
//匿名對象調用
Thread t2 = new Thread(usRunnable);//方式二
/**
* 線程的終止
* 1、stop()
* 2、interrupt()、isInterrupted()、interrupted()
* 三者區別,interrupt()線程的中斷標識位,isInterrupted()檢查線程的中斷標識位,interrupted(),檢查並修改爲false
*/
t1.stop();//強行終止,不建議使用,資源不正常釋放造成死鎖,過於野蠻。
t1.interrupt();//中斷線程,設置標識位將其改爲true
t2.interrupt();
/**
* 線程其他的方法
*/
try {
t1.setDaemon(true);//守護線程
t2.join();//加入線程--之前的所以線程都加入
t1.wait();//阻塞等待線程
t1.setPriority(5);//線程的優先級--平均5
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}