首先我們來說一說Runnable接口和Thread類,因爲start()涉及到了多線程併發,所有我們來看看開啓多線程的兩個方法
在實現單任務時通常用Runnable接口,多任務時一般用Thread類 ,Thread與Runnable是繼承關係,Thread繼承了Runnable的接口,可以使用更多的方法和成員。
實現並啓動線程有兩種方法
1、寫一個類繼承自Thread類,重寫run方法。用start方法啓動線程
2、寫一個類實現Runnable接口,實現run方法。用new Thread(Runnable target).start()方法來啓動
1.繼承Thread類
/**
* @(#)TestThre.java
*
*
* @author
* @version 1.00 2020/5/10
*/
public class TestThre {
public static void main(String[] args){
new MyThread().start();
new MyThread().start();
}
static class MyThread extends Thread{
private int tickets = 5;
public void run(){
while(true){
System.out.println("Thread ticket = "+tickets--);
if(tickets<0){
break;
}
}
}
}
}
改進後的代碼,在this指針上加了一個synchronized鎖,實現了線程同步。
/**
* @(#)NewThre.java
*
*
* @author
* @version 1.00 2020/5/10
*/
public class NewThre extends Thread {
private int tickets = 5;
public void run(){
for(int i=0;i<5;i++){
synchronized(this){
if(this.tickets>0){
try{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"賣票--->"+(this.tickets--));
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args){
NewThre t3 = new NewThre();
new Thread(t3,"線程一").start();
new Thread(t3,"線程二").start();
}
}
2. 實現Runnable接口
/**
* @(#)RunnableTest.java
*
*
* @author
* @version 1.00 2020/5/10
*/
public class RunnableTest {
public static void main(String[] args){
myThread dt = new myThread();
new Thread(dt).start();
new Thread(dt).start();
}
static class myThread implements Runnable{
private int tickets = 5;
public void run(){
while(true){
System.out.println("Runnable ticket = "+tickets--);
if(tickets<0){
break;
}
}
}
}
}
其次,再來談談start()和run()方法
start()方法用來開啓線程,在開啓線程後自動調用run()方法
- 調用start()方法後會創建一個線程,此時的線程處於就緒狀態,並放到等待隊列,等待CPU執行,通過JVM,線程Thread會調用run()方法,run()f方法體包含所要執行的代碼,在run()方法運行結束以後,CPU開始調度其它線程。在start()方法開啓一個線程後,並不需要等待後面的run()方法執行,可以直接執行後面的代碼。
- run()方法用來運行線程,run()方法當做普通方法的方式調用,程序順序執行,等待run()方法執行完畢以後,才能繼續執行下面的代碼。這是在沒有開啓多線程的情況下,程序中只有一個主線程。