方法一
- 新建類如MyThread繼承Thread類
- 重寫run()方法
- 再通過new MyThread類來新建線程
- 通過start方法啟動新線程
案例:
class MyThread extends Thread {public MyThread(String name) {super(name);}@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println(this.getName() + " " + i );}}}主類:MyThread myThread1 = new MyThread("Thread-1");MyThread myThread2 = new MyThread("Thread-2");MyThread myThread3 = new MyThread("Thread-3");myThread1.start();myThread2.start();myThread3.start();
常用方法
- static void sleep(T):讓當前線程睡T毫秒
- static void yield():當前線程從運行變為就緒狀態,重新爭奪cpu
- void run():執行線程中run()方法(在當前線程中執行)
- void start():開啟一個新的線程執行run()方法
- void setName():設置這個線程的名稱
- String getName():獲取當前線程的名稱
- void interrupt():中斷執行的子線程
- void join():等該線程執行完后,再執行當前線程
例:
當前主線程需等待t01,t02,t03線程執行完后再執行。
方法二
- 創建新類MyThread實現Runnable接口
- 實現接口中的run方法
- 創建MyThread對象,再新建Thread對象,將MyThread對象作為構造方法的參數傳入Thread
- 通過start方法啟動新的線程
案例:
class MyThread implements Runnable {@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName() + " " + i );}}
}
主類main方法中MyThread myThread1 = new MyThread();Thread myThread2 = new Thread(myThread1);Thread myThread3 = new Thread(myThread1);myThread2.start();myThread3.start();
方法三
- 新建類MyThread實現Callable接口
- 實現接口中的call方法(有返回值)
- 創建MyThread對象,創建FutureTask對象將MyThread對象當作構造方法參數傳入
- 創建Thread對象將FutureTask對象當構造方法參數傳入(類似方法二第三步)
- 通過start方法啟動新線程
- 通過FutureTask對象get方法獲取返回結果
案例:
class MyThread implements Callable{@Overridepublic Object call() throws Exception {for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName() + " " + i );}Thread.sleep(5000);return 10+20;}
}main方法中:FutureTask futureTask = new FutureTask(new MyThread());Thread thread = new Thread(futureTask);thread.start();Object result = futureTask.get();System.out.println("執行結果:"+result);
實際過程中會出現多線程相關問題,比如兩個線程同時操控一個實例變量或共享變量,可能會存在數據不一致等問題。
編程模型
同步編程模型:線程一執行必須等待線程二執行結束,或相反,兩個線程發生了等待關系。
異步編程模型:線程一和線程二同時執行。
解決方法
方法一
synchronized(鎖的內容,通常為全局唯一例如類main.class){
執行的內容
}
方法二
通過Lock lock = new ReentrantLock()對象來上鎖
lock.lock();//上鎖
執行的內容
lock.unlock();//解鎖
守護線程
一般是一個死循環,所有用戶結束,守護線程也就結束。
開啟方法
void setDaemon(true);
方法四
通過wait()和notify(),notifyAll()方法等待和喚醒線程。
線程池
多線程運行時,系統不斷創建和銷毀新的線程,成本非常高,使用線程池就是最好的選擇。
創建
ExecutorService threadPoll = Executors.newCachedThreadPool();
threadPoll.execute(對象):線程池指派一個線程執行該對象run方法。
關閉線程池
threadPoll.shutdown();
多把鎖
創建
CountDownLatch countDownLatch = new CountDownLatch(鎖的數量);
鎖數量減少
countDownLatch.countDown(); //鎖的數量減一
等待
countDownLatch.await():等待子線程執行完再執行(鎖的數量為0)
感謝觀看——