多线程启动定时器 会等待上一次执行完成?_Java多线程
生活随笔
收集整理的這篇文章主要介紹了
多线程启动定时器 会等待上一次执行完成?_Java多线程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
進程和線程的區別
進程:操作系統應用程序。占用系統的 cpu 和內存線程:是進程更小的執行單元。一個進程可以有多個線程。線程與線程之間是相互獨立的,但是是要共用進程的資源。區別:每個進程都需要操作系統為其分配獨立的內存地址空間,而同一進程中的所有線程在同一塊地址空間中,這些線程可以共享數據,因此線程間的通信比較簡單,消耗的系統開銷也相對較小。
Thread 線程類
構造方法
Thread?thread?=?new?Thread();Thread?thread?=?new?Thread(線程對象,"線程名字");
靜態方法
"查看線程最大級別":Thread.MAX_PRIORITY"查看線程最小級別":Thread.MIN_PRIORITY
"查看線程默認級別":Thread.NORM_PRIORITY
常用方法
"讓線程開始執行":thread.start();??"自動調用線程的run()方法""返回線程的名字":thread.getName();
"返回線程的優先級":thread.getPriority();
"等待線程死亡":thread.join();
"等待線程死亡":thread.join(毫秒);
"給線程設置名字":thread.setName(名字);
"讓線程睡眠":thread.sleep(毫米數);
"當前線程讓出強占cpu的機會??自己馬上處于就緒狀態":thread.yield();
線程狀態
- 新建狀態(New):使用new 關鍵字創建線程對象,僅僅被分配了內存
- 就緒狀態(Ready):線程對象被創建后,等待它的 start 方法被調用,以獲得 CPU 的使用權
- 運行狀態(Running):執行 run 方法,此時的線程的對象正占用 CPU
- 睡眠狀態(Sleeping):調用 sleep 方法,線程被暫停,睡眠時間結束后,線程回到就緒狀態,睡眠狀態的線程不占用 CPU
- 死亡狀態(Dead):run 方法執行完畢后,線程進入死亡狀態
- 阻塞狀態(Blocked):線程由于某些事件(如等待鍵盤輸入)放棄 CPU,暫停運行,直到線程重新進入就緒狀態,才有機會轉到運行狀態
創建多線程的方法
繼承 Thread 類
實現步驟:
????//?重新run方法就是創建了多線程
????@Override
????public?void?run()?{
????????//?放需要執行的代碼
????}
????//?使用
????public?static?void?main(String[]?args)?{
????????MyThread?et1?=?new?MyThread();
????????//?使用start方法執行
????????et1.start();
????}
}
實現 Runnable+Thread 類的帶參構造
實現步驟:
實現 Runnable 接口創建多線程程序的好處:
????//?實現run方法
????@Override
????public?void?run()?{
????????//?放需要執行的代碼
????}
????//?使用
????public?static?void?main(String[]?args)?{
????????//?用Runnable的接口實現類的實例作為Thread的target
????????Thread?t1?=?new?Thread(new?MyRunnable());
????????//?調用
????????t1.start();
????}
}
實現 Callable+Future 模式
public?class?CallableTest?{????public?static?void?main(String[]?args)?throws?Exception?{
????????Callable?call?=?new?Callable()?{@Overridepublic?Integer?call()?throws?Exception?{//?需要執行的代碼//?返回值為Integerreturn?1;
????????????}
????????};//?Future就是對于具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、獲取結果//?FutureTask類實現了RunnableFuture接口,RunnableFuture繼承了Runnable接口和Future接口
????????FutureTask?task?=?new?FutureTask<>(call);
????????Thread?t?=??new?Thread(task);
????????t.start();
????}
}
匿名內部類
匿名內部類作用:簡化代碼
????public?static?void?main(String[]?args){
????????//?第一個方法,使用Runnable的方式
????????new?Thread(new?Runnable()?{
????????????@Override
????????????public?void?run()?{
????????????????//?需要執行的代碼
????????????}
????????}).start();
????????//?第二個方法
????????new?Thread(){
????????????@Override
????????????public?void?run(){
????????????????//?需要執行的代碼
????????????}
????????}.start();
????}
}
java.util.Timer 工具類
public?class?TimerTest?{????public?static?void?main(String[]?args)?throws?Exception?{
?????????//?啟動定時器線程,并在10000毫秒后執行TimerTask實例的run方法,每隔3000毫秒執行一次
????????new?Timer().schedule(new?TimerTask()?{
????????????@Override
????????????public?void?run()?{
????????????????//?需要執行的代碼
????????????}
????????},?10000,3000);
????}
}
java.util.concurrent.Executors 工具類
public?class?ThreadPoolTest?{????public?static?void?main(String[]?args)?{
????????//?創建線程池,10個
????????//?通過java.util.concurrent.ExecutorService接口對象來執行任務
????????//?該接口對象通過工具類java.util.concurrent.Executors的靜態方法來創建
????????ExecutorService?threadPool?=?Executors.newFixedThreadPool(10);
????????while(true)?{
????????????threadPool.execute(new?Runnable()?{?//?提交多個線程任務,并執行
????????????????@Override
????????????????public?void?run()?{
????????????????????//?需要執行的代碼
????????????????}
????????????});
????????}
????}
}
線程同步方法
同步代碼塊
用synchronized(互斥鎖)把代碼包裹起來,必須是同一把鎖注意:
????"出現線程安全的邏輯"
}
同步方法
- 在方法的定義上面加synchronized 關鍵字
public?synchronized?void?sale()?{"對象鎖?(必須是同一把鎖?saleWindow)"
?if?(tickets?<=?30)?{
??System.out.println(Thread.currentThread().getName()?+?"賣了第"?+?tickets?+?"張");//?獲得當前線程的名稱
??tickets++;
?}
?try?{
??Thread.sleep(400);
?}?catch?(InterruptedException?e)?{
??e.printStackTrace();
?}
}
//?等同于上面的鎖方法
private?Object?o?=?new?Object();
private?int?count?=?1;
public?void?sale2(){
????"上鎖"
????synchronized(o){
????????count++;
????}
}
- 鎖定靜態方法
//?這里相當于synchronized(T.class)
//?因為在靜態方法中沒有this
public?synchronized?static?void?m(){
????count++:
}
public?static?void?n(){
????synchronized(T.class){
????????count++;
????}
}
- 可重入鎖
synchronized?void?t1(){
????//?執行邏輯
????t2();
}
synchronized?void?t2(){
????//?執行邏輯
}
Lock+ReentranLock 手動上鎖
private?Integer?tickets?=?1;"創建一把鎖"
private?Lock?lock?=?new?ReentrantLock();
public?void?run()?{
?for?(int?i?=?1;?i?<=?100;?i++)?{
??"手動上鎖"
??lock.lock();
??if?(tickets?<=?100)?{
???tickets++;
??}
??try?{
???Thread.sleep(100);
??}?catch?(InterruptedException?e)?{
???e.printStackTrace();
??}
??"手動解鎖"
??lock.unlock();
?}
}
sleep、yield、join 和 wait
- sleep 和 yield 都是 Thread 類的靜態方法,都會使當前處于運行狀態的線程放棄 CPU,但兩者的區別在于:
- join 方法用于等待其它線程結束,當前運行的線程可以調用另一線程的 join 方法,當前運行線程將轉到阻塞狀態,直至另一線程執行結束,它才會恢復運行
- wait 方法是 Object 類的方法,讓當前線程等待,直到另一個線程調用該對象的 notify()方法或 notifyAll()方法才會執行,必須是鎖對象才能調用
END
往期推薦
SpringBoot
RocketMQ整合SpringBoot
Solr整合SpringBoot
Spring全家桶教程
圖靈學院微服務教程
總結
以上是生活随笔為你收集整理的多线程启动定时器 会等待上一次执行完成?_Java多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何告别半途而废——韦东山嵌入式Linu
- 下一篇: 用迭代法求 平方根