概念
進程:受操作系統管理的基本運行單元
線程:在進程中獨立運行的子任務,是操作系統能夠進行運算調度的最小單位,一個進程中至少有一個線程,可以有多個線程
單線程:一個進程中只有一個線程
多線程:一個進程中的線程多餘一個,多線程是異步執行的
多線程
優點:能夠充分的利用CPU,提高代碼的響應速度
缺點:線程太多,線程之前的切換
線程的使用方式
1、繼承Thread類
任務執行類
public class MyThread extends Thread {
@Override
public void run(){
System.out.println("MyThread");
}
}
運行類代碼
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
System.out.println("運行結束");
}
運行結果
2、實現Runnable接口
由於Java是單繼承的,所以一個類如果已經繼承了一個父類,那麼這個類就不能再繼承Thread類了,這個時候就可以實現Runnable接口來達到與繼承Thread類同樣的效果
任務執行類
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("MyThread");
}
}
運行類代碼
public class TestMyRunnable {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
System.out.println("運行結束");
}
}
線程調用的隨機性
從上面的代碼運行的結果來看,線程的調用是隨機的
實例變量與線程安全
在自定義的線程類中,實例變量有共享與不共享之分,下面是實例不共享的例子
任務執行類
public class MyThread extends Thread {
private int count = 5;
public MyThread(String name) {
super(name);
this.setName(name);
}
@Override
public void run() {
while (count > 0) {
System.out.println("Thread" + Thread.currentThread().getName() + ":" + count);
}
}
}
運行類代碼
public class TestMyThread {
public static void main(String[] args) {
MyThread t1 = new MyThread("A");
MyThread t2 = new MyThread("B");
MyThread t3 = new MyThread("C");
MyThread t4 = new MyThread("D");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
運行結果
變量共享
任務執行類
public class MyThread extends Thread {
private int count = 5;
public MyThread(String name) {
super(name);
this.setName(name);
}
@Override
public void run() {
// 這裏不要使用for循環,因爲使用同步後其他線程就得不到運行的機會了
count--;
System.out.println("Thread" + Thread.currentThread().getName() + ":" + count);
}
}
運行類代碼
public class TestMyThread {
public static void main(String[] args) {
MyThread t1 = new MyThread("A");
Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t1);
Thread thread3 = new Thread(t1);
Thread thread4 = new Thread(t1);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
運行結果
從上面的結果來看是線程不安全的,爲了線程安全,我們可以在run方法上加上synchronized關鍵字,結果如下