天天看點

Java并發程式設計的藝術-讀書筆記

多線程不一定比單線程快

當累加操作少于百萬次時,單線程執行的速度會比多線程執行的速度快,因為線程有建立和上下文切換的開銷

vmstat的cs表示每秒上下文切換的次數

如何減少多線程上下文切換次數

使用無鎖并發程式設計,CAS算法,使用最少線程和使用協程

死鎖

死鎖樣例:

public class DeadLockDemo {

    /** A鎖 */
	private static String A = "A";
    /** B鎖 */
	private static String B = "B";

	public static void main(String[] args) {
		new DeadLockDemo().deadLock();
	}

	private void deadLock() {

		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (A) {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (B) {
						System.out.println("1");
					}
				}
			}
		});

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (B) {
                    synchronized (A) {
                        System.out.println("2");
                    }
                }
            }
        });

        t1.start();
        t2.start();
    }
}
           

現實場景中,比如t1拿到鎖之後,因為一些異常情況沒有釋放鎖(死循環)。又或者是t1拿到一個資料庫鎖,釋放鎖的時候抛出了異常,沒釋放掉,就會出現死鎖

避免死鎖的常用辦法

  1. 避免一個線程同時擷取多個鎖。
  2. 避免一個線程在鎖内同時占用多個資源,盡量保證每個鎖隻占用一個資源。
  3. 嘗試使用定時鎖,使用lock.tryLock(timeout)來替代使用内部鎖機制。
  4. 對于資料庫鎖,加鎖和解鎖必須在一個資料庫連接配接裡,否則會出現解鎖失敗的情況。

volatile的應用

volatile是輕量級的synchronized,它在多處理器開發中保證了共享變量的可見性

可見性的意思是當一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值

volatile定義與實作原理

java程式設計語言允許線程通路共享變量,為了確定共享變量能被準确和一緻地更新,線程應該確定通過排他鎖單獨獲得這個變量。

Java語言提供了volatile,在某些情況下比鎖要更加友善。如果一個字段被聲明成volatile,Java線程記憶體模型確定所有線程看到這個變量的值是一緻的

volatile會增加Lock字首指令

Lock字首指令會引起處理器緩存回寫到記憶體

一個處理器的緩存回寫到記憶體會導緻其他處理器的緩存無效

synchronized

JVM基于進入和退出Monitor對象來實作方法同步和代碼塊同步

代碼塊同步是使用monitorenter和monitorexit指令實作的,而方法同步是使用另外一種方式實作的

鎖的4種狀态

無鎖,偏向鎖,輕量級鎖,重量級鎖

鎖可以更新不能降級,目的是為了提高獲得鎖和釋放鎖的效率

單例模式中的雙重檢測鎖

public class UnsafeLazyInitialization {
  private static Instance instance;
  public static Instance getInstance() {
    if (instance == null)			// 1:A線程執行
        instance = new Instance();	// 2:B線程執行
        return instance;
  }
  static class Instance {
  }
}
           

隊列同步器

獨占鎖

繼續閱讀