Java 线程 知识
?學習線程 先了解 線程與進程之間的關系
? 線程:
?(線程是cpu調度的最小單位)
我們可以說是進程中執行運算的最小單位。
進程:
(進程是資源分配的最小單位)
我們可以說是一段程序執行的過程,
如果還是不清楚2著的話可以打一個比喻 進程 相當于火車, 線程就是火車的沒一個車廂.?
-----------------------------------------------------------------------------------------------------------------------------------------------
?創建線程
Java 提供了三種創建線程的方法:
- 通過實現 Runnable 接口;
- 通過繼承 Thread 類本身;
- 通過 Callable 和 Future 創建線程。
1 實現Runnable 的接口
?步驟 1.1 建立Runnable 對象
? ? ? 1.2 使用參數為Runnable 對象的構造方法創建Thread實例
? ? ? 1.3 調用start方法啟動線程
一個小demo
package me;
public class Main{public static void main(String[] args){Thread thread = new Thread(new Task());thread.start();}static class Task implements Runnable{@Overridepublic void run() {for (int i=0;i<5;i++){System.out.println(i);try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}}}}}
這個就是創建了一個類Task實現Runnable , 最后創建Thread 然后關聯類Task?
2 繼承Thread類
package me;public class Th extends Thread{public static void main(String[] args){Test test = new Test();test.start();}static class Test extends Thread{@Overridepublic void run() {for (int i=0;i<10;i++){System.out.println(i);try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}}}}}
因為Test 繼承了Thread 所以這里沒有在new Thread,
?
3?通過 Callable 和 Future 創建線程。
package me;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class Main implements Callable<Integer> {public static void main(String[] args) {Main main = new Main();FutureTask<Integer > futureTask = new FutureTask<>(main);Thread thread = new Thread(futureTask);thread.start();}@Overridepublic Integer call() throws Exception {int i = 0;for (; i < 5; i++) {System.out.println(i);Thread.sleep(1500);}return i;}}
?
線程的生命周期
?
?
?
這個出生就是創建狀態, 就緒狀態, 執行狀態,等待狀態,死亡狀態,休眠,阻塞狀態
有時候我們看別的地方說5中,6中7中, 其實是吧休眠和阻塞當做一種了,? 這個自己心里知道就行,
不過各個狀態還是需要知道
?
線程的操作方法
?1 線程休眠?
調用sleep()方法
?例如Thread.sleep(2000) 等待2秒
2 線程加入
?當某個線程使用join()方法加入到另一個線程時,另一個線程等待該線程執行完畢以后在繼續執行
?3 線程禮讓
使用yield()方法
?yield 方法是具有同樣優先級的線程進入可執行狀態的機會,
4 中斷線程
以前使用stop 不過這個方法已經過時了
現在提倡使用在run()方法里面使用無線循環形式,然后使用一個布爾型標記控制循環停止
?
如果線程使用了sleep()或wait()方法進入就緒狀態,可以使用Thread類中的interrupt()方法是線程離開run()方法,同時線程結束
會拋出異常,用戶可以處理該異常時完成線程的中斷業務處理
線程同步與異步
線程同步使用 Synchronized 關鍵字 ,
同步可以比喻成大家排隊上公交, 異步就是一起上沒有順序
異步的一個demo
package me;
public class Main {public static void main(String[] args) {Main demo = new Main();//創建2個線程new Thread(){@Overridepublic void run() {while (true){demo.setName("張三");}}}.start();new Thread(){@Overridepublic void run() {while (true){demo.setName("李四");}}}.start();}public void setName(String str){for ( int i=0;i<str.length();i++){System.out.print(str.charAt(i));}System.out.println();}}
.
并沒有順序
同步 demo
package me;import com.sun.source.tree.SynchronizedTree;public class Main {public static void main(String[] args) {Main demo = new Main();//創建2個線程new Thread(){@Overridepublic void run() {while (true){demo.setName("張三");}}}.start();new Thread(){@Overridepublic void run() {while (true){demo.setName("李四");}}}.start();}public void setName(String str){synchronized (this){for ( int i=0;i<str.length();i++){System.out.print(str.charAt(i));}System.out.println();}}}
?
當然我們還可以使用lock()方法來實現同步效果
package me;import com.sun.source.tree.SynchronizedTree;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Main {Lock lock = new ReentrantLock();public static void main(String[] args) {Main demo = new Main();//創建2個線程new Thread() {@Overridepublic void run() {while (true) {demo.setName("張三");}}}.start();new Thread() {@Overridepublic void run() {while (true) {demo.setName("李四");}}}.start();}public void setName(String str) {lock.lock();//加鎖try{for (int i = 0; i < str.length(); i++) {System.out.print(str.charAt(i));}System.out.println();}finally {lock.unlock();//解鎖}}}
使用lock 記得使用try 方法不然要發生異常了, 就沒法解鎖了 ,try 方法可以很好的處理
lock 是jdk? 1.5之后出現的非常好用
?
線程死鎖
有時候2個或者多個線程需要在幾個共享對象上獲取鎖,可能會導致死鎖
一般我們是使用synchronized不當的時候就是引起死鎖
一個死鎖的案例
public void add(int[] a1,int[]a2){int value = 0;int size = a1.length;if (size == a2.length){synchronized (a1){synchronized (a2){for (int i=0;i<size;i++){value =a1[i]+a2[i];}}}System.out.println(value);}}
?避免死鎖
盡量避免在同一把鎖的代碼中用到另一把鎖資源,還盡量避免使用全局對象
我們也可以使用資源排序的技術? 就是A和B , B必須獲得A上的鎖然后才能獲取B上的鎖,一旦A獲取A上的鎖線程B 必須等待A上的鎖
?
總結下線程上使用的方法
.wait() //當前線程掛起
.notify()// 喚醒正在排隊等待同步資源的線程中優先級最高者結束等待
.notifyAll()// ?喚醒正在排隊等待資源的所有線程結束
?
Thread.sleep(); //線程休眠
Thread.yield()//暫停當前線程的執行,讓具有同樣優先級的線程進入可執行狀態的機會
.start() ?//線程開始
?
?
總結
以上是生活随笔為你收集整理的Java 线程 知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 加密狗多少钱啊?
- 下一篇: Java成员变量与成员方法