Java线程的使用及共享协作
創建線程的三種方式
1、繼承Thread;
static class MyThread extends Thread{@Overridepublic void run() {//do something...} } public static void main(String[] args) throws InterruptedException {MyThread thread = new MyThread ();thread.start(); }2、實現Runnable接口(該接口無返回值);
static class MyRunnable implements Runnable {public void run() {//do something...} } public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new MyRunnable(),"MyRunnable");thread.start(); }3、實現Callable接口(該接口有返回值,在之前的SpringMvc中有提到過)
static class MyCallable implements Callable<String> {public String run() {String result = "";//do something...return result;} } public static void main(String[] args) throws InterruptedException {FutureTask<String> task = new FutureTask<String>(MyCallable);new Thread(task).start();//獲取結果值String result = task.get(); }jdk也提供了通過了創建線程池的方式去創建線程,但是線程池底層及時通過去創建Thread對象創建線程的,所以只有這三種方式
線程共享協作
先來認識一下 synchronized?這個關鍵字,這個在大部分網上都能找到相關的資料,這里就簡單的說明一下:
synchronized鎖也叫內置鎖,可用于兩種情況,1、修飾在靜態方法上,即類鎖;2、修飾在普通方法上或者synchronized代碼塊,即對象鎖。示例如下:
//類鎖: public synchronized static void function(){//do something...} //對象鎖: //修飾方法,同一個對象同一時刻只能有一個線程執行該方法 public synchronized void function(){...} //synchronized 代碼快 public void function(){synchronized(this){//鎖住當前對象(this可替換成其他對象,即只有執行完當前代碼塊后,才能釋放,同一時刻,當前線程獲取到對象鎖后,才能執行,其他線程進入等待阻塞狀態)//...} }volatile關鍵字:適合于只有一個線程寫,多個線程讀的場景,因為它只能確保可見性。
ThreadLocal:可以參考ThreadLocal詳解,這篇講的挺詳細的
wait(),notify()/notifyAll()
wait():即等待通知,作用于對象上,當前線程調用對象的wait()方法會使進入阻塞狀態并釋放當前持有鎖,需和synchronized一起使用,等待當前對象調用notify/notifyAll()方法之后,需重新競爭到鎖后,方可繼續執行,未被喚醒則一直等待。
notify()/notifyAll():作用于對象上,用來喚醒阻塞狀態的wait()方法,需和synchronized一起使用,執行完后,需繼續執行后面的程序才能釋放當前持有鎖,一般將該方法放于最后。
public void function () {//...synchronized (this) {//do something...notify();}//... }notify()喚醒隨機一個wait()方法阻塞線程,而notifyAll()則是喚醒所有的wait()阻塞線程,wait()被喚醒后,需重新去競爭鎖,才能繼續執行。
wait(long mills):即等待超時方法,即等待mills毫秒后,如若時間到后未收到喚醒,則繼續執行后面的代碼。
long overtime = now+T; long remain = T;//等待的持續時間 while(result不滿足條件&& remain>0){wait(remain);remain = overtime – now;//等待剩下的持續時間 } return result;join()
可以將并行執行的線程變成串行執行模式,可以理解為插隊執行,以下為示例:
static class Worker implements Runnable{private Thread thread;public Worker(Thread thread) {this.thread = thread;}public void run() {try {System.out.println(thread.getName()+"start join...");thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" terminte..." + System.currentTimeMillis());}}public static void main(String[] args) throws InterruptedException {System.out.println(Thread.currentThread().getName()+" start..." + System.currentTimeMillis());Thread main = Thread.currentThread();Thread thread1 = new Thread(new Worker(main),"join1");Thread thread2 = new Thread(new Worker(thread1),"join2");Thread thread3 = new Thread(new Worker(thread2),"join3");thread1.start();thread2.start();thread3.start();System.out.println(Thread.currentThread().getName()+" sleep...");try {Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+" end...");} catch (InterruptedException e) {e.printStackTrace();}}執行結果為:
main start...1616734827339 main sleep... mainstart join... join2start join... join1start join... main end... join1 terminte...1616734828340 join2 terminte...1616734828340 join3 terminte...1616734828340即在當前線程中調用其他線程的join()方法后,其他線程就會進去到阻塞狀態,只有等待當前線程執行完成后,其他線程才能繼續執行,由并行變成串行;
join()方法里面也是由wait()方法去處理的
總結
以上是生活随笔為你收集整理的Java线程的使用及共享协作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter、ReactNative、
- 下一篇: 一年Java经验应该会些什么