馮諾依曼體系
操作系統
是一個軟件,搞管理的軟件,一方面管理計算機硬件設備,另一方面管理計算機軟件資源。
一個完整的操作系統=內核+配套的應用程序。
操作系統具體管理主要是兩件事:
1.描述
2.組織
進程:
對於操作系統來說,一個任務就是一個進程(Process)。
進程是操作系統的非常重要的軟件資源
如果把一個可執行程序跑起來,系統就會創建一個對應的進程,如果把這個程序結束了,系統就會隨之銷燬進程,進程可以看成是一個程序的執行“過程”。(是動態性的)
進程是操作系統進行資源分配的最小單位。
但進程一般是很多的,CPU太少了,從微觀上看,一個CPU同一時刻只能執行一個進程的指令,這時通過“併發”的方式,讓CPU快速調度,微觀上仍是串行執行,但是調度速度很快,宏觀上感覺就是在多個進程齊頭並進。
在進程調度時,有搶佔式調度方式,,哪怕某個進程只工作了一半,也隨時可能被打斷。
線程
thread
如果把進程想象成一個工廠,線程就是 工廠中的若干流水線。
1.線程是包含在進程裏的
2.一個進程可能有多個線程
3.同一個進程中的很多線程之間,是共享了一些資源的。(進程之間是不能共享的)
線程是輕量級:進程,
引進線程原因:
創建一個線程比創建一個進程成本低
銷燬一個線程比銷燬一個進程成本也低
成本低的原因是,新建一個線程,不需要給這個線程分配很多新資源,大部分線程之間都是和原來的線程資源共享的,如果創建一個進程,就需要給這個進程分配較多資源。
線程是操作系統進行調度和執行的最小單位
一個線程是一個pcb,一個進程是多個pcb(使用線程組Id來標識,哪些pcb從屬同一個進程)。
一個進程中的多個線程之間可以併發工作,但也有限,一個進程中的線程不能太多否則就不會再提高效率了,反而會拖慢。
一個進程中的線程數:
1.CPU個數
2.和線程執行的任務類型也相關
任務類型:
1.CPU密集型:程序一直在執行計算任務
2.IO密集型:程序沒咋進行計算,主要進行輸入輸出操作
同時,多線程工作也是有不安全風險的,比如線程之間搶資源,或者一個線程出現異常,並沒有處理好,那其他線程也就沒辦法工作了
創建線程
public class ThreadDemo1 {
static class MyThread extends Thread {
@Override
public void run() {
System.out.println("hello world");
}
}
public static void main(String[] args) {
//需要使用Thread類 還需指定這個線程要執行哪些指令
//重寫Thread中的run方法
//Thread對象被創建出來時,內核中並沒產生線程
Thread t = new MyThread();
//執行start方法才創建了一個線程
t.start();
}
}
其實上面代碼涉及兩個線程,Mythread創建出來的線程,main中對應的主線程。
代碼實現串行,並行
public class ThreadDemo2 {
private static long count = 10000000000L;
public static void main(String[] args) {
seriaL();
concurrency();
}
private static void concurrency() {
long beg = System.currentTimeMillis();
Thread t1 = new Thread() {//匿名內部類
@Override
public void run() {
int a = 0;
for(long i = 0;i<count;i++) {
a++;
}
}
};
Thread t2 = new Thread() {//匿名內部類
@Override
public void run() {
int b = 0;
for(long i = 0;i<count;i++) {
b++;
}
}
};
t1.start();
t2.start();
try {
//讓主線程等待t1,t2執行結束
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//t1和t2和main線程之間都是併發進行的
long end = System.currentTimeMillis();
System.out.println("time:"+(end-beg)+"ms");
}
private static void seriaL() {
long beg = System.currentTimeMillis();//獲取時間戳
int a = 0;
for(long i = 0;i<count;i++) {
a++;
}
int b = 0;
for(long i = 0;i<count;i++) {
b++;
}
long end = System.currentTimeMillis();
System.out.println("time:"+(end-beg)+"ms");
}
}
可得並行執行時間會得以提高
創建線程方法:
1.可以通過顯示繼承Thread類方式實現
2.也可以通過匿名內部類方式繼承Thread類
3.創建一個類,實現Runnable接口,然後把這個Runnable的實例關聯到Thread實例上。
public class ThreadDemo3 {
static class MyRunnable implements Runnable {
//本質是描述了要執行的任務代碼是啥
@Override
public void run() {
System.out.println("我是新線程");
}
}
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
}
}
4.也可以使用內名內部類去重寫runnable裏的run方法來創建線程。
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("我是新線程");
}
};
Thread t = new Thread(runnable);
t.start();
5.也可以使用lambda表達式
Thread t = new Thread(()-> {
System.out.println("我是一個新線程");
});
t.start();