Java線程筆記

1.方法前加上synchronize可以將方法變爲同步。

2.線程調用start()的順序不代表線程調用的順序。

3.線程之間的數據不同享,如果要共享需要加上synchronize關鍵字。
MyThread myThread=new MyThread();
Thread t1=new Thread(myThread)。
Thread t2=new Thread(myThread);

4.println(i--);雖然println是同步的方法,但是i--發生在參數中,synchronize是在方法體中。

5.線程的構造方法是在main線程中,mythread.run()方法在main線程中,mythread.start()在本線程中。

6.Thread thread=new Thread(MyThread mythread);
    this.getName());//爲mythread.getName();
    Thread.currentThread().getName();//爲thread.getName();
7.isAlive();//測試線程是否已啓動,或者還未終止。
8.sleep();//使線程休眠
9.getId();//獲取線程的唯一標識
10.停止線程
stop();//廢棄,不安全
suspend();//廢棄,不安全
調用的方法加上了synchronized,容易造成獨佔的缺點。
suspend(),方法運行到println()時,使用suspend()暫停,println()的鎖未釋放,導致不能打印後面的println(),使得運行結果不同步。
resume();//廢棄,不安全
interrupt();//推薦

11.線程中斷
interrupt();
interrupted();
isInterrupted();

12.yield();//放棄當前的cpu資源,將它讓給其它的任務去佔用cpu執行時間。yeild()將cpu讓給其他資源導致速度變慢。

13.線程的優先級。線程的優先級分爲1~10個等級。
優先級的繼承性:A線程啓動B線程,B線程的優先級與A線程是一樣的。
優先級的規則性:高優先級的線程大部分先執行完。
優先級的隨機性:優先級高的線程不一定先執行完。

14.守護線程。
Java中有兩種線程,一種是用戶線程,另一種是守護線程。
任何一個守護線程都是JVM中所有非守護線程的“保姆”,只要當前JVM中存在任何一個非守護線程沒有結束,守護線程就在工作。
只有當最後一個非守護線程結束時,守護線程才隨着JVM一同結束工作。

15.兩個Thread同時操作一個對象,對象只有一個實例變量,出現變量覆蓋,在方法前加上synchronized。

16.只用共享的資源才需要同步化,需要加上synchronized。

17.A線程持有object的鎖,B線程可以以異步方式調用object的非synchronized方法。

18.A線程調用了object的synchronized的X方法(非static),相當於A線程獲得了對象object的鎖,B線程可以調用Object的非synchronized方法,但是想要調用synchronized方法,必須等A線程完成X方法。

19.synchronized擁有鎖重入的功能。加了synchronized的方法可以調用本類中加了synchronized的方法。
子類的synchronized方法可以調用父類的synchronized方法。
當同步synchronized方法發生異常,同步鎖會釋放。
子類重寫父類的synchronized方法,需要在子類的方法前加上synchronized才能使子類的方法同步。

20.synchronized同步語句塊。
使用同步代碼塊synchronized(this){}來代替同步方法synchronized method()。
不在synchronized塊中的就是異步執行,在synchronized塊中的就是同步執行。
線程A調用了Object的synchronized(this)代碼塊,線程B想要調用Object的其它synchronized(this)代碼塊或者是synchronized方法,必須等線程A執行結束後才能調用。

21.將任意對象作爲對象監視器
1)synchronized(非this對象){},一般是實例變量及方法的參數。
2)synchronized(非this對象){}與synchronized(this){}或者是synchronized方法是異步的。
    synchronized(this){}不能加在靜態方法裏面。
3)synchronized(非this對象){},非this對象必須爲同一個對象,方法纔是同步的,如果是不同的對象,仍然爲異步。
4)synchronized持有不同對象監視器是異步的。

22.synchronized(非this對象x){};
1)多個線程同時執行synchronized(非this對象x){},同步代碼呈現同步效果。當其它線程執行x對象中synchronized同步方法呈現同步效果。如果使用不同的x對象,則爲異步。
2)其它線程執行x對象中的synchronized方法時,爲同步。
3)其它線程執行x對象中的synchronized(this){}時,爲同步。

23.synchronized加在static靜態方法上是給Class類上鎖,加在非static靜態方法上是給對象上鎖。
synchronized加在static靜態方法前的效果等價於synchronized(xx.Class){}
synchronized加在非靜態方法前的效果等價於synchronized(this){}

24.synchronized(str);//給String類型上鎖時,如果String值一樣,則會導致公用同一把鎖,導致同步。

25.在將任何數據類型作爲同步鎖時,需要注意是否有多個線程同時持有鎖對象,如果同時持有,則這些線程是同步的;如果分別獲得鎖對象,則這些線程就是異步的。
只要對象不變,即使對象的屬性改變,還是同步。


26.volatile關鍵字,主要作用是使變量在多個線程可見,就是強制從公共堆棧中取值。
啓動線程時,線程中的變量會存在於公共堆棧和私有堆棧中,私有堆棧和公共堆棧是不同步的。JVM爲-server模式,線程一直在私有堆棧中取值。mian函數中,即使改變了線程中變量的值,改變的也只是公共堆棧中的值,並沒有改變私有堆棧中的值。
使用場合,多個線程中可以感知實例變量被改變,可以獲得最新的值。

27.volatile和synchronized的比較
1)volatile的性能比synchronized性能更好。
2)volatile只用於修飾變量,synchronized用於修飾方法,代碼塊。
3)多線程訪問volatile不會發生阻塞,而訪問synchronized會發生阻塞。
4)volatile可以保證數據的可見性,不能保證數據的原子性;而synchronized可以保證原子性,從而間接保證可見性,synchronized會將私有內存和公共內存中的數據同步。
5)volatile解決的是變量在多個線程之間的可見性;synchronized解決的是線程訪問資源的同步性。
線程安全包含原子性和可見性兩個方面,Java的同步機制都是圍繞這兩個方面來確保線程安全的。

28.查看jvm是否發生死鎖
cd C:\Program Files\Java\jdk1.8.0_121\bin
jps
jstack -l id

29.synchronized的兩個特性:互斥性和可見性。
synchronized可以解決一個線程看到對象處於不一致的狀態,還可以保證進入同步方法或者同步代碼塊的每個線程,都看到由同一個鎖保護之前所有的修改效果。

30.線程的等待/通知機制。
wait();//使處於臨界區的線程進入等待狀態,釋放被synchronized線程同步的鎖。
notify();//隨機喚醒一個因調用wait()操作而處於阻塞狀態中的線程,使其進入就緒狀態。如果沒有處於阻塞狀態的線程,方法被忽略。僅通知一個線程。
notifyAll();//使所有正在等待隊列中等待同一共享資源的”全部“線程從等待狀態退出,進入可運行狀態。此時,優先級最高的線程優先執行,也可能隨機執行。
等待/通知機制的實現。
1)需要先調用wait()方法,才能調用notify()方法。notify()方法執行後不會立即釋放鎖。

31.線程狀態切換

32.方法notify()執行後,不釋放鎖,必須執行完notify()方法所在的同步synchronized()所在的代碼塊纔會釋放鎖。

33.當線程是wait()狀態,調用interrupt()方法會報錯。

34.總結
1)執行完同步代碼塊就會釋放對象的鎖。
2)執行同步代碼塊時,遇到異常,鎖也會被釋放。
3)執行了鎖所屬對象的wait()方法,這個線程會釋放對象鎖,此線程會進入線程等待池,等待被喚醒。

35.wait(long timeout)在timeout毫秒之後會被喚醒,或者可以調用notify喚醒。

36.通過管道進行線程之間的通信:字節流。
pipeStream:一個線程發送數據到輸出管道,另一個線程從輸入管道中心讀取數據。

37.join()方法。
作用:阻塞當前線程,噹噹前線程中調用子線程的run()方法結束,子線程銷燬,接着執行當前線程。
join與synchronized區別:
1)join是在內部使用wait()方法進行等待。
2)synchronized則是使用”對象監視器“原理作爲同步。

38.join()方法和interrupt()方法如果彼此遇到,會出現異常。

39.join(long timeout)和sleep區別,join()內部是使用wait()方法實現,鎖會被釋放。

40.類ThreadLocal
類ThreadLocal解決的是變量在不同線程間的隔離性,也就是不同線程擁有自己的值,不同線程的值可以放入ThreadLocal類中進行保存。
ThreadLocal首次get()值爲null,可以在initialValue()中設置初始值。
InheritableThreadLocal類繼承可以繼承父線程中的值,需要重寫childValue(Object parentValue)方法。

41.使用ReentrantLock類實現同步。lock()上鎖,unlock()解鎖。是對對象的監視器。

42.使用ReentrantLock類和Condition實現等待/通知。
使用condition.await()使線程進入等待狀態。
使用condition.signal();和condition.signalAll();實現通知。、

43.Object類與Condition類   類比
wait()  <==>  await()
wait(long timeout)  <==>  await(long timeout)
notify()  <==>  signal()
notifyAll()  <==>  signalAll()

44.公平鎖和非公平鎖
公平鎖:線程獲取鎖的順序是按照線程加鎖的順序來分配的,先來先得。
非公平鎖:隨機獲得鎖,可能會造成某些線程一直拿不到鎖。
ReentrantLock lock=new ReentrantLock(fair);

45.getHoldCount();返回當前線程調用lock()方法的次數。

46.getQueueLength();返回正等待獲取此鎖定的線程估計數。

47.ReentrantReadWriteLock類
ReentrantLock具有完全互斥排他的效果,即同一時間只有一個線程在執行ReentrantLock.lock()方法後面的任務。雖然保證安全,但是效率低。
ReentrantReadWriteLock類可以加快運行效率。
讀操作相關鎖:共享鎖。
寫操作相關鎖:排他鎖。
多個讀鎖之間不互斥,讀鎖與寫鎖互斥,寫鎖與寫鎖互斥。
ReentrantReadWriteLock().readLock().lock();
ReentrantReadWriteLock().readLock().unlock();

ReentrantReadWriteLock().writeLock().lock();
ReentrantReadWriteLock().writeLock().unlock();

48.定時器的使用
Timer()類是設置計劃任務,封裝任務的類是TimerTask()。執行計劃任務的代碼需要放入TimerTask的子類中。
    private static Timer timer=new Timer();
    static public class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("運行了!時間爲:"+new Date());
        }
    }
    //執行
    timer.schedule(task,dateRef);

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