java線程之基礎學習

 java線程之基礎學習總結 

線程實現的兩種方式:

java中可以有兩種方式實現多線程操作,一種是繼承Thread類,另外一種是實現Runnable接口。

繼承Thread

Thread類是在java.lang包中定義的

一個類只要繼承Thread類,要覆寫run()方法。

簡單實例

定義MyThread

  1. 定義MyThread類 
  2. public class MyThread extends Thread { 
  3.     private String name; 
  4.     public MyThread(String name) { 
  5.         this.name = name; 
  6.     } 
  7.     public void run() { 
  8.         for (int i = 0; i < 5; i++) { 
  9.             System.out.println(name + "運行:" + i); 
  10.         } 
  11.     } 

編寫TestThread類調用: 

  1. public class TestThread { 
  2.     public static void main(String[] args) { 
  3.         MyThread myThread1 = new MyThread("singsong1"); 
  4.         MyThread myThread2 = new MyThread("singsong2"); 
  5.         myThread1.run(); 
  6.         myThread2.run(); 
  7.     } 
  1. 運行結果: 
  2. singsong1運行:0 
  3. singsong1運行:1 
  4. singsong1運行:2 
  5. singsong1運行:3 
  6. singsong1運行:4 
  7. singsong2運行:0 
  8. singsong2運行:1 
  9. singsong2運行:2 
  10. singsong2運行:3 
  11. singsong2運行:4 

從結果可以發現,此時的執行非常的有規律,先執行完第一個對象,再執行第二個對象。

run()方法換成start();一旦調用start()方法,則會通過JVM找到run()方法

Public void start()

使用start()方法啓動線程:

  1. public class TestThread { 
  2.     public static void main(String[] args) { 
  3.         MyThread myThread1 = new MyThread("singsong1"); 
  4.         MyThread myThread2 = new MyThread("singsong2"); 
  5.         myThread1.start(); 
  6.         myThread2.start(); 
  7.     } 
  1. 運行結果: 
  2. singsong1運行:0 
  3. singsong1運行:1 
  4. singsong2運行:0 
  5. singsong1運行:2 
  6. singsong2運行:1 
  7. singsong1運行:3 
  8. singsong2運行:2 
  9. singsong1運行:4 
  10. singsong2運行:3 
  11. singsong2運行:4 

從運行結果可以知道,程序時交互式的運行。

因爲需要用到CPU的資源,所以每次的運行結果基本是都不一樣的

不要調用Thread類或Runnable對象的run方法。直接調用run方法,只會執行同一個線程中的任務,而不會啓動新線程。應該調用Thread.start()方法。這個方法將創建一個執行run方法的新線程。


Runnable接口的實現

簡單實例

  1. public class RunnableThread implements Runnable { 
  2.     private String name; 
  3.     public RunnableThread(String name) { 
  4.         this.name = name; 
  5.     } 
  6.     public void run() { 
  7.         for (int i = 0; i < 5; i++) { 
  8.             System.out.println(name + "運行:" + i); 
  9.         } 
  10.     } 

編寫TestThread1調用 

  1. public class TestThread1 { 
  2.     public static void main(String[] args) { 
  3.          RunnableThread runnableThread1=new RunnableThread("singsong1"); 
  4.          RunnableThread runnableThread2=new RunnableThread("singsong2"); 
  5.         Thread thread1= new Thread(runnableThread1); 
  6.         Thread thread2= new Thread(runnableThread2);      
  7.         thread1.start(); 
  8.         thread2.start();          
  9.     } 
 
  1. 運行結果: 
  2. singsong1運行:0 
  3. singsong1運行:1 
  4. singsong2運行:0 
  5. singsong2運行:1 
  6. singsong2運行:2 
  7. singsong2運行:3 
  8. singsong2運行:4 
  9. singsong1運行:2 
  10. singsong1運行:3 
  11. singsong1運行:4 

Thread類和Runnable接口區別

最大區別是在於資源的共享

如果一個類繼承Thread,則資源共享不可共享。而實現Runable接口,能實現資源共享。

例如:

MyThread

  1. public class MyThread extends Thread { 
  2.     private int ticket = 5
  3.     private String name; 
  4.     public MyThread(String name) { 
  5.         this.name = name; 
  6.     } 
  7.     public void run() { 
  8.         for (int i = 0; i < 15; i++) { 
  9.             if (ticket > 0) { 
  10.                 System.out.println(name + "正售出第 " + (ticket--) + "票"); 
  11.             } 
  12.         } 
  13.     } 
  14.  
  15. 調用: 
  16. public class TestThread { 
  17.     public static void main(String[] args) { 
  18.         MyThread myThread1 = new MyThread("singsong1"); 
  19.         MyThread myThread2 = new MyThread("singsong2"); 
  20.         myThread1.start(); 
  21.         myThread2.start(); 
  22.     } 
  23. 運行結果: 
  24. singsong1正售出第 5票 
  25. singsong1正售出第 4票 
  26. singsong1正售出第 3票 
  27. singsong1正售出第 2票 
  28. singsong1正售出第 1票 
  29. singsong2正售出第 5票 
  30. singsong2正售出第 4票 
  31. singsong2正售出第 3票 
  32. singsong2正售出第 2票 
  33. singsong2正售出第 1票 

重複售出了一次

再來看看Runnable接口是怎麼實現資源共享的

RunnableThread

  1. public class RunnableThread implements Runnable { 
  2.     private int ticket = 5
  3.     private String name; 
  4.     public RunnableThread(String name) { 
  5.         this.name = name; 
  6.     } 
  7.     public void run() { 
  8.         for (int i = 10; i > 0; i--) { 
  9.             if (ticket > 0) { 
  10.                 System.out.println(name + "正售出第 " + (ticket--) + "票"); 
  11.             } 
  12.         } 
  13.     } 

 編寫TestThread1調用:

 

  1. public class TestThread1 { 
  2.     public static void main(String[] args) { 
  3.         RunnableThread runnableThread1 = new RunnableThread("singsong1"); 
  4.         Thread thread1 = new Thread(runnableThread1); 
  5.         Thread thread2 = new Thread(runnableThread1); 
  6.         thread1.start(); 
  7.         thread2.start(); 
  8.     } 
  9. 運行結果: 
  10. singsong1正售出第 5票 
  11. singsong1正售出第 4票 
  12. singsong1正售出第 3票 
  13. singsong1正售出第 2票 
  14. singsong1正售出第 1票 

從運行結果可以得出實現Runnable接口的優點。

大家有沒有想過Runnable接口爲什麼能實現資源的共享,而Thread類不能

 本人個人理解

首先看如下代碼: 

  1. public class TestThread1 { 
  2.     public static void main(String[] args) { 
  3.         RunnableThread runnableThread1 = new RunnableThread("singsong1"); 
  4.         RunnableThread runnableThread2 = new RunnableThread("singsong2"); 
  5.         Thread thread1 = new Thread(runnableThread1); 
  6.         Thread thread2 = new Thread(runnableThread2); 
  7.         thread1.start(); 
  8.         thread2.start(); 
  9.     } 

此代碼是在TestThread1類的繼承上修改的:添加了    RunnableThread runnableThread2 = new RunnableThread("singsong2");

runnableThread1換成runnableThread2

現在我們在運行程序看看結果:

  1. singsong1正售出第 5票 
  2. singsong1正售出第 4票 
  3. singsong1正售出第 3票 
  4. singsong1正售出第 2票 
  5. singsong1正售出第 1票 
  6. singsong2正售出第 5票 
  7. singsong2正售出第 4票 
  8. singsong2正售出第 3票 
  9. singsong2正售出第 2票 
  10. singsong2正售出第 1票 

 

從結果可以知道也重複了一次。

 

總結一下:也是就說Runnable接口能實現資源的共享是因爲用同一個實現Runnable接口的子類來創建不同的線程,去執行同一個任務。而Thread卻沒有這種機制。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章