2018.4.23
線程
多線程和多進程:
線程:
在一個軟件中,負責不同功能的子程序,稱之爲線程。
進程:
是在計算機系統中所有正在運行的程序都可以看做是一個進程,多進程的操作系統。
計算機常識問題:
windows操作系統是一個多任務的操作系統,爲什麼windows可用同時執行多任務???
從表面上看:windows的確可以同時執行不同的應用程序,同時執行:eclipse 還有QQ 玩遊戲,一些電腦管家類的軟件,會提示你,關閉掉佔用網絡較多和內存佔用較多的程序。 爲什麼?
降低CPU,內存,網絡的使用率,給遊戲提供更好的 運行環境。
從實際出發:
CPU其實是一個傻子,一次只能做一件事情,但是執行力很強。每一個CPU的內核在一個時間片內
只能執行一件事情。但是這個時間片非常的短,不同的程序會出現在不同的時間片上,不斷地切換
所以感覺是在 同時運行,
現在的CPU基本上都是多核多線程的
面試題:
請問一個java程序在運行的時候,最少有幾個線程???
最少是兩個線程:1.main線程 2.JVM的垃圾回收機制。
多線程的好處:
1.可以讓一個程序同時知悉不同的任務
2.可以提高資源的利用率
多線程的弊端:
1.線程安全問題 之前的迭代器。
2.增加了CPU負擔
3.降低了其他程序CPU的執行概率
4.容易出現死鎖行爲。
如何創建一個線程
兩種方式:
1.自定義一個類繼承Thread類,那麼這個類就可以看作是一個多線程類
2.要求【重寫】Thread裏面的run方法,吧需要執行的自定義線程代碼放入run
class MyThread extends Thread{
//要求重寫【run】方法
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("自定義Thread類" + i);
}
}
}
public class Demo1 {
public static void main(String[] args) {
//1.創建自定義線程類的類對象
MyThread myThread = new MyThread();
//2.啓動線程,嘗試調用run方法
//myThread.run();嘗試調用run方法,相當於調用了一個普通的方法,而不是一個線程
myThread.start();//啓動線程的方式,會發現,MyThread線程和main線程在搶佔CPU資源
for (int i = 0; i < 10; i++) {
System.out.println("main線程"+i);
}
}
/*
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
//遍歷第一種方式
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//遍歷的第二種方式
for (String string : list) {
System.out.println(string);
}
//遍歷的第三種方式
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
*/
}
結果:
main線程0
自定義Thread類0
main線程1
自定義Thread類1
自定義Thread類2
自定義Thread類3
自定義Thread類4
自定義Thread類5
自定義Thread類6
自定義Thread類7
自定義Thread類8
自定義Thread類9
main線程2
main線程3
main線程4
main線程5
main線程6
main線程7
main線程8
main線程9
線程實例
用線程同時
小芳視頻和小紅聊天
class VideoThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("和小芳視頻中........");
}
}
}
class ChatThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
}
System.out.println("和小紅聊天中........");
}
}
public class Demo1 {
@Test //註解
public void test1() {
VideoThread videoThread = new VideoThread();
ChatThread chatThread = new ChatThread();
videoThread.start();
chatThread.start();
}
}
線程常用方法
線程中的常用方法:
thread(String name);初始化線程名字,屬於線程的一個有參數的構造方法。
setName(String name);修改線程的名字
getName();獲取線程的名字。
static sleep();static靜態方法,通過Thread類名調用,這裏需要處理一些異常,要求當前線程睡覺多少毫秒。
【哪一個熱線執行了sleep方法,哪一個線程就睡覺】
static currentThread();static靜態方法,返回當前的線程對象
【哪一個線程執行了currentThread方法,就返回哪一個線程對象】
getPriority(); 返回當前線程的優先級CPU執行的優先級,不是絕對的。
setPriority(int newPriority); 設置線程的優先級。
【注意】
線程的優先級範圍是1-10,10最高,1最低
這裏的優先級只是提高了當前線程用於CPU執行權概率,並不能完全保證當前線程能夠一定會佔用更多的cpu時間片。
線程默認的優先級是5
37:Thread[main,5,main]
Thread[線程名,優先級,線程組名]
interface A {
public void testA();
}
public class Demo2 extends Thread implements A{
public Demo2(String name) {
super(name);
}
@Override
public void testA() {
//這裏也無法拋出異常,兩種處理方法,第一種,捕獲異常,第二種,在接口聲明方法部分,聲明該異常。
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
//這裏是Demo2線程對象的線程代碼
System.out.println("27:"+Thread.currentThread());
for (int i = 0; i < 20; i++) {
System.out.println("自定義線程");
/*
在其他方法中,使用sleep方法,可以拋出可以捕獲,但是在run方法中爲什麼只有捕獲沒有拋出??
這是一個語法規則:在java中,重寫父類的方法,要求和父類的方法聲明一模一樣,在Thread類中】
run方法沒有拋出異常,所以在子類中,你也不能拋出異常,要和父類一致。
*/
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
//這裏是main線程。
Demo2 demo2= new Demo2("狗蛋");
//demo2.setName("狗娃");
demo2.setPriority(10);
demo2.start();//開啓自定義線程,這裏是自定義線程中的run方法裏面的線程
System.out.println("37:"+Thread.currentThread());
for (int i = 0; i < 20; i++) {
System.out.println("這裏是main線程");
sleep(10);
}
}
}