春節的時候去面試了一家公司,筆試題里面有一道是使用簡單的代碼實現線程的‘死鎖’,當時沒有想到這道題考的是Synchronized關鍵字,于是自己定義了兩個資源模擬了一下。后面想想腸子都悔青了,于是自己在電腦上敲了一遍,同時也是對自己的一個提醒,基礎功夫還不夠扎實。
Synchronized關鍵字
JAVA語言的關鍵字,當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。
- 當兩個并發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以后才能執行該代碼塊。
- 然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
- 尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
- 第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
- 以上規則對其它對象鎖同樣適用.
代碼示例
package test160118; public class TestSynchronized { public static void main(String[] args) { Sy sy = new Sy(0); Sy sy2 = new Sy(1); sy.start(); sy2.start(); } } class Sy extends Thread { private int flag ; static Object x1 = new Object(); static Object x2 = new Object(); public Sy(int flag) { this.flag = flag; } @Override public void run() { System.out.println(flag); try { if (flag == 0) { synchronized (x1) { System.out.println(flag+"鎖住了x1"); Thread.sleep(1000); synchronized (x2) { System.out.println(flag+"鎖住了x2"); } System.out.println(flag+"釋放了x1和x2"); } } if(flag == 1) { synchronized (x2) { System.out.println(flag+"鎖住了x2"); Thread.sleep(1000); synchronized (x1) { System.out.println(flag+"鎖住了x1"); } System.out.println(flag+"釋放了x1和x2"); } } } catch (InterruptedException e) { e.printStackTrace(); } } }
總結
總之說多了都是淚,關鍵不是我不會而是我沒有想到它考的都是這個。也不知道面試過沒過,有點方。后面會陸陸續續把之前面試時答得不是很好的幾道題寫成專欄的。