線程啊是個好東西,可是平時工做不多本身建立線程,因此一些基礎的操做可能就不容易記起來,這篇文章常看看有益身心健康java
public class TestDeamon { public static void main(String[] args) { // lambda 表達式 Thread t1 = new Thread(()->System.out.println("這是一個線程01!")); Thread t2 = new Thread(()->{ System.out.println("這是一個線程02!"); }); // 匿名內部類 Thread t3 = new Thread(){ @Override public void run() { System.out.println("這是一個線程03!"); } }; // 繼承Thread Thread t4 =new MyThread04(); // 實現Runnable 參數是Runnable Thread t5 = new Thread(new MyRunnable()); // 時效內 // 啓動線程 t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } } /** * 繼承Thread * public class Thread implements Runnable * thread是實現了Runnable接口 */ class MyThread04 extends Thread{ @Override public void run() { System.out.println("這是一個線程04!"); } } /** * 實現Runnable */ class MyRunnable implements Runnable{ @Override public void run() { System.out.println("這是一個線程05!"); } }
// 啓動線程 t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); 輸出: 這是一個線程01! 這是一個線程02! 這是一個線程03! 這是一個線程04! 這是一個線程05!
線程啓動以後就會執行run方法ide
執行完for循環 自動結束測試
// lambda 表達式 Thread t1 = new Thread(()->{ for (int i = 0; i < 10; i++) { try{ Thread.sleep(1000); System.out.println("==="); } catch (Exception e) { e.printStackTrace(); } } }); t1.start();
stop已經被廢棄,stop太粗暴,不溫柔,因此沒人喜歡..spa
// lambda 表達式 Thread t1 = new Thread(()->{ for (;;) { try{ Thread.sleep(1000); System.out.println("==="); } catch (Exception e) { e.printStackTrace(); } } }); t1.start(); // 10秒後 中止 Thread.sleep(10000); // 中止 t1.stop();
很容易產生數據不一致 由於某一個事務或者一塊代碼沒執行完的時候 就有可能被幹掉 線程
舉個例子:code
// lambda 表達式 Thread t1 = new Thread(()->{ System.out.println("對象去洗澡了"); try{ System.out.println("鑽被窩等着..."); Thread.sleep(10000); System.out.println("洗白白 開小會"); } catch (Exception e) { e.printStackTrace(); } }); t1.start(); // 10秒後 中止 Thread.sleep(5000); // 中止 t1.stop(); 結果: 對象去洗澡了 鑽被窩等着... 能夠看到哈,你等了半天,還沒開始開小會就被打斷了 。。
suspend 讓線程暫停 對象
resume 讓暫停的線程繼續執行繼承
suspend容易產生死鎖等問題 若是忘記resume或者resume異常 那若是suspend的線程持有鎖的話,就死鎖了接口
public class TestDeamon03 { // 鎖 表示對象 public static Object obj = new Object(); public static void main(String[] args) throws InterruptedException { // lambda 表達式 Thread t1 = new Thread(()->{ synchronized (obj){ try { System.out.println("我出去打工了 留對象在家"); Thread.sleep(10000); System.out.println("我回來了 娶我對象 "); } catch (Exception e) { e.printStackTrace(); } } }); t1.start(); // 2秒後 暫停 Thread.sleep(2000); // 暫停 t1.suspend(); Thread.sleep(2000); // 恢復 resumeObj(t1); } // resume 模擬異常 static void resumeObj(Thread t){ int i = 1/0; t.resume(); } }
你找了個對象,把人家放家裏,說打工1年回來娶,而後你回家途中找了個別人,一塊兒幸福生活了,你對象在家...事務
被你佔用,你又不通知、不釋放
volatile(保證內存可見)修飾一個變量 時間可能控制不是很精確 由於volatile修改了以後刷新到內存 在另外一個線程讀取到 仍是須要時間的 雖然很快 可是通常的狀況 都沒什麼問題
public class TestDeamon04 { static volatile boolean flag = true; public static void main(String[] args) throws InterruptedException { // lambda 表達式 Thread t1 = new Thread(()->{ int count =0; // flag == true 循環 flag==false 中止循環 也就結束線程了 while (flag) { try { Thread.sleep(1); count++; } catch (Exception e){ e.printStackTrace(); } } System.out.println("count:"+count); }); t1.start(); // 1秒後 中止 Thread.sleep(1000); flag = false; } } 屢次輸出結果: 50五、52五、50七、512 能夠看到每次輸出結果是不肯定的 , 這種方式只能保證到達某個條件了就中止線程 可是不能控制線程準確點中止 好比你想讓一個線程循環100次就中止 很難準確控制
也算標誌位 可是比volatile高級一點 好比sleep、wait等操做會被中斷
// lambda 表達式 final Thread t1 = new Thread(()->{ int count =0; // while (!Thread.interrupted()) { try { count++; } catch (Exception e){ e.printStackTrace(); } } System.out.println("count:"+count); }); t1.start(); // 1秒後 中止 Thread.sleep(1000); t1.interrupt();
中斷sleep測試:interrupt會中斷sleep在異常捕獲裏邊break就好了 而標誌位flag是沒法作到的
public class TestDeamon06 { static volatile boolean flag = true; public static void main(String[] args) throws InterruptedException { // lambda 表達式 final Thread t1 = new Thread(()->{ // while (!Thread.interrupted()) { try { Thread.sleep(20000000); } catch (Exception e){ break; } } System.out.println("interrupted 結束 "); }); // lambda 表達式 final Thread t2 = new Thread(()->{ while (flag) { try { Thread.sleep(20000000); } catch (Exception e){ break; } } System.out.println("volatile-結束"); }); t1.start(); t2.start(); // 1秒後 中止 Thread.sleep(1000); t1.interrupt(); flag = false; } }
總結:
stop 、suspend resume 已廢棄
volatile標誌位 沒法中斷sleep wait 等操做
interrupt 至關於標誌位可是能夠中斷sleep wait等操做 捕獲InterruptedException異常 進行線程結束
可能還有其餘方式 大多數是基於標誌位的
有問題能夠留言哦,或者公衆號留言(回覆快):