java之Synchronized(锁住对象和锁住代码)
1、問題
Synchronized我們一般都知道是鎖,但是我們怎么區分是鎖對象還是鎖代碼呢?
?
2、測試Demo
package leetcode.chenyu.test;public class Synchronized {class Test {public synchronized void testFirst() {print("testFirst");}public void testSecond() {synchronized(this) {print("testSecond");}}public void testThird() {synchronized(Test.class) {print("testThird");}}public void print(String method) {System.out.println(method + "start");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(method + "end");}}class TestThread extends Thread {public int mType = 0;public Test mTest = null;public TestThread(int type, Test test) {this.mType = type;this.mTest = test;}public void run() {if (mTest == null) {if (mType == 1) {Test test = new Test();test.testFirst();}else if (mType == 2) {Test test = new Test();test.testSecond(); } else if (mType == 3) {Test test = new Test();test.testThird(); }} else {if (mType == 1) {mTest.testFirst();}else if (mType == 2) {mTest.testSecond(); }else if (mType == 3) {mTest.testThird(); }}}}public static void main(String[] args) {Synchronized syn = new Synchronized();Test test = syn.new Test();for (int i = 0; i < 5; ++i) {syn.new TestThread(1, null).start();}}
}
?
3、運行結果和分析
?
1)、按照上面的運行結果
testFirststart testFirststart testFirststart testFirststart testFirststart testFirstend testFirstend testFirstend testFirstend testFirstend?
2)、把for循環里面的代碼換如下
?
syn.new TestThread(2, null).start();運行結果如下
testSecondstart testSecondstart testSecondstart testSecondstart testSecondstart testSecondend testSecondend testSecondend testSecondend testSecondend對于上面1)、2)、兩種情況,synchronized(this)以及非static的synchronized方法,只能防止多個線程同時執行同一個對象的同步代碼段,鎖的是對象,也就是鎖的本身this, 由于每個線程都新構建了一個新的對象,所以加了synchronized沒有鎖住。
?
3)、把for循環里面的代碼換如下
syn.new TestThread(1, test).start(); syn.new TestThread(2, test).start();運行結果都一樣如下
testSecondstart testSecondend testSecondstart testSecondend testSecondstart testSecondend testSecondstart testSecondend testSecondstart testSecondend這里由于我們幾個現場都共用一個對象,所以對象固定了,所以就鎖住了,其它線程在沒有釋放鎖的時候,進不來。
4)、把for循環里面的代碼換如下
syn.new TestThread(3, null).start(); syn.new TestThread(3, test).start();結果都如下
testThirdstart testThirdend testThirdstart testThirdend testThirdstart testThirdend testThirdstart testThirdend testThirdstart testThirdendsynchronized(Test.class)實現了全局鎖的效果,不管對象是不是一樣的,都是同樣的效果,就鎖住代碼了
?
我么一般用這個比較多。
?
?
?
?
4、總結
1、synchronized加在非靜態方法前和synchronized(this)都是鎖住了這個類的對象,如果多線程訪問,對象不同,就鎖不住,對象固定是一個,就可鎖住。
2、synchronized(類名.class)和加在靜態方法前,是鎖住了代碼塊,不管多線程訪問的時候對象是不是同一個,能縮小代碼段的范圍就盡量縮小,能在代碼段上加同步就不要再整個方法上加同步,縮小鎖的粒度。
?
?
?
?
?
?
?
4、總結
總結
以上是生活随笔為你收集整理的java之Synchronized(锁住对象和锁住代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java之通过FileChannel实现
- 下一篇: Android studio之导入pro