java之執行緒建立的兩種方式,六種狀態和匿名內部類建立子類或實現類物件
阿新 • • 發佈:2018-12-10
一.匿名內部類建立子類或實現類物件
new Test(){}
相當於建立了Test類的子類物件
並且沒有類名
建立介面實現類
new 介面名() {};介面實現類的物件
注意 : new 後邊是類或者介面名 大括號內是類或者介面中的方法
public class Kll { public static void main(String[] args) { Test test = new Test() { @Override public void fun() { System.out.println("重寫fun方法"); } }; test.fun(); // 建立介面實現類 // new InterA() {};介面實現類的物件 // 注意 : new 後邊是類或者介面名 // 大括號內是類或者介面中的方法 InterA a = new InterA() { @Override public void fun() { System.out.println("介面實現類方法"); } }; a.fun(); // 匿名內部類直接呼叫方法 new InterA() { @Override public void fun() { System.out.println("哈哈哈哈哈"); } }.fun();; } } class Test{ public void fun() { System.out.println("Test類中的fun方法"); } } interface InterA{ public abstract void fun(); }
二.多執行緒
標準單執行緒程式
-
好處:程式碼安全
-
弊端:執行效率低 多執行緒
-
程序:一個正在執行的程式就是一個程序
-
一個程序可以有一個或多個執行緒
-
執行緒:執行的任務
-
分時排程:
- CPU同一時間,只能執行一個任務(CPU單核單執行緒的原因)
- 現在要同時執行多個任務
- 這時CPU就會為這幾個任務開闢相應獨立的執行路徑
-
(執行路徑 執行功能的程式碼)
- CPU會在多個任務之間進行快速切換
- 搶佔資源:搶奪CPU的執行資源,改變任務的優先順序
-
多執行緒好處:
- 提高任務的執行效率(執行緒本身也會消耗系統資源,建立執行緒要把握一個度,不是越多越好)
main呼叫 1.jvm呼叫main函式1.jvm呼叫main函式 2.CPU就為main凱比一個獨立的執行路徑 3.這個路徑就執行main中的程式碼3.這個路徑就執行main中的程式碼 程式只有一個主執行緒,除了主執行緒,其他的都叫子執行緒 這個主執行緒的名字就叫main
- 執行緒的名字:
- 主執行緒:main* 主執行緒:main
- 子執行緒:預設 Thread-x(x從0開始)* 子執行緒:預設 Thread-x(x從0開始)
建立方式:
-
執行緒建立方式1(繼承Thread類,重寫run方法)
-
執行緒建立方式2(使用Runnable介面建立執行緒)
-
建立放式1:繼承方式
- 1.增加類和類的耦合度
- 2.java中,類只能單繼承
執行緒開啟方法:start()方法。 執行的任務就是重寫run方法。 run方法和start方法的區別: 1.直接呼叫run方法,就是相當於呼叫成員方法 2. 直接呼叫start 開啟執行緒(建立獨立執行路徑) 3.執行緒中執行的任務 是run方法中的程式碼
public class Kll {
public static void main(String[] args) {
// 異常發生在 主執行緒中
// 建立子執行緒
SubThread t1 = new SubThread();
// 開啟執行緒
// 執行的任務就是重寫run方法
t1.start();
SubThread t2 = new SubThread();
t2.start();
for (int i = 0; i < 50; i++) {
System.out.println("main---" + i);
}
System.out.println("main");
}
}
// 建立子執行緒類
class SubThread extends Thread{
// 重寫run方法
@Override
public void run() {
//System.out.println(10 / 0);
for (int i = 0; i < 50; i++) {
System.out.println("run---" + i);
}
}
}
獲取當前執行緒名字和給執行緒設定名字:
public class Kll extends Thread{
public static void main(String[] args) {
NameThread n1 = new NameThread("哈哈");
n1.setName("啾啾");
n1.start();
NameThread n2 = new NameThread();
n2.start();
// 獲取當前正在執行的執行緒物件
// 放在哪兒個執行緒中,就表示哪兒個執行緒物件
Thread thread = Thread.currentThread();
// 列印主執行緒名字
System.out.println(thread.getName());
}
}
class NameThread extends Thread{
// 構造方法
public NameThread() {
// TODO Auto-generated constructor stub
}
public NameThread(String name) {
super(name);
}
// 重寫run方法
@Override
public void run() {
for (int i = 0; i < 50; i++) {
//獲取執行緒的名字
//System.out.println(this.getName() + "--" + i);
System.out.println(Thread.currentThread().getName() + "++" + i);
}
}
}
父類使用了final修飾set/get方法 ,子類不能重寫
可以使用不同的方法名來解決
執行緒在記憶體中的表現符合棧記憶體特點 : 先進後出。
NameTread ta = new NameTread();開闢了一個新棧(相當於CPU獨立執行空間)。
ta.start();必須呼叫開啟執行緒方法,這個棧才能執行程式碼。
執行的程式碼就是執行緒類中run方法。
- 建立方式2:實現方式
- 1.介面可以多實現(靈活)
- 2.將執行緒要執行的方法從類中分離出來
public class Kll {
public static void main(String[] args) {
// 建立介面實現類物件
RunnableImpl ruImpl = new RunnableImpl();
// 建立執行緒類物件
Thread t = new Thread(ruImpl);
// 開啟執行緒
t.start();
}
}
class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
- 匿名內部類 建立執行緒程式碼:
public class Kll {
public static void main(String[] args) {
// 執行緒類的子類建立
Thread t1 = new Thread() {
@Override
public void run() {
System.out.println("執行緒子類的run方法");
}
};
t1.start();
// 介面類的實現類建立執行緒
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("介面實現類");
}
};
// 建立執行緒物件
Thread t2 = new Thread(r1);
t2.start();
// 合併一起
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("介面實現類和執行緒物件合併");
}
});
t3.start();
}
}
三.執行緒的六種狀態
-
執行緒休眠方法(測試時常用)。
- sleep(long time);單位毫秒;效果:卡住你當前的執行緒
- 注意: 書寫的位置,決定休眠哪兒個執行緒。
-
執行緒的6種狀態:
- new 新建狀態
- runnable 執行狀態
- blocked 受阻塞狀態
- waiting 等待狀態
- timed waiting 休眠狀態
- terminated 死亡狀態
-
執行緒呼叫了start方法 就一定會進入執行狀態嗎?
- 不會,必須得到CPU的資源才會進入執行狀態。
- 執行緒呼叫了start方法而是得到了CPU的執行權。
- 沒有得到CPU執行資源的執行緒,會進入受阻塞狀態。
- 當受阻塞狀態的執行緒得到了CPU的執行資源,這是會從受阻塞—>執行狀態。
- 不會,必須得到CPU的資源才會進入執行狀態。
-
執行狀態–>休眠狀態 相當於放棄了 CPU的執行權
-
等休眠時間結束 重新獲得CPU的執行權
-
等到用notify()方法 重新獲得CPU的執行權
-
注意 :wait()和notify()方法是Object類中的方法
六種狀態轉換圖: 執行緒休眠程式碼: 注意 : 父類中的run方法沒有丟擲異常 子類中只能自己處理(try…catch)
public class Demo10 {
public static void main(String[] args) throws InterruptedException {
// 執行緒休眠
// 單位毫秒
// 效果:卡住你當前的執行緒
// 注意: 書寫的位置,決定休眠哪兒個執行緒
Thread.sleep(1000);
System.out.println("main");
TestBThread tb = new TestBThread();
tb.start();
}
}
class TestBThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
// 休眠一秒
// 注意 : 父類中的run方法沒有丟擲異常
// 子類中只能自己處理(try...catch)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + i);
}
}
}