JAVA synchronized正確理解

昨天看blog:http://blog.csdn.net/zyplus/article/details/6672775有這樣一段話java

「在JAVA中,是沒有相似於PV操做、進程互斥等相關的方法的。JAVA的進程同步是經過synchronized()來實現的,須要說明的是,JAVA的synchronized()方法相似於操做系統概念中的互斥內存塊,在JAVA中的Object類型中,都是帶有一個內存鎖的,在有線程獲取該內存鎖後,其它線程沒法訪問該內存,從而實現JAVA中簡單的同步、互斥操做。明白這個原理,就能理解爲何synchronized(this)與synchronized(static XXX)的區別了,synchronized就是針對內存區塊申請內存鎖,this關鍵字表明類的一個對象,因此其內存鎖是針對相同對象的互斥操做,而static成員屬於類專有,其內存空間爲該類全部成員共有,這就致使synchronized()對static成員加鎖,至關於對類加鎖,也就是在該類的全部成員間實現互斥,在同一時間只有一個線程可訪問該類的實例。若是隻是簡單的想要實如今JAVA中的線程互斥,明白這些基本就已經夠了。但若是須要在線程間相互喚醒的話就須要藉助Object.wait(), Object.nofity()了。」網絡

寫的很是不錯,這裏畫個圖,補充個測試程序。ide

也就是分清楚到底鎖住的是那一部份內存,也就是類和類的實例 內存關係。測試


測試程序以下:this

package com.jdcloud.xue.gang;spa


import java.util.concurrent.CountDownLatch;操作系統

import java.util.concurrent.ExecutorService;.net

import java.util.concurrent.Executors;線程


public class StaticMutiThread extends Thread{對象


public static final int SIZE=100;

//作個靜態鎖出來

static final Object LOCKER = new Object();


static int addint =0;

ExecutorService executor;

CountDownLatch countDownLatch;


public StaticMutiThread(ExecutorService executor,

CountDownLatch countDownLatch) {

super();

this.executor = executor;

this.countDownLatch = countDownLatch;

}


public void addPrint(){

synchronized (LOCKER) { //把這裏的LOCKER換成this,來測試多個Thread同步試一試

try {

Thread.sleep(100L);

} catch (InterruptedException e) {

e.printStackTrace();

}

addint +=1;

System.out.println("add int is :" + addint);

countDownLatch.countDown();

}

}// //鎖住實例化出來的對象的內存。


public void run() {

addPrint();

}

class Runner{

public void runit(StaticMutiThread staticMutiThread){

executor.execute(staticMutiThread);

}


}


//測試Main方法

public static void main(String args[]) throws InterruptedException{

//用於關閉線程池

 CountDownLatch countDownLatch = new CountDownLatch(SIZE);

//線程池

 ExecutorService executor = Executors.newFixedThreadPool(SIZE);

 

for(int i =0;i<SIZE;i++){

//new一個線程出來

StaticMutiThread staticMutiThread = new StaticMutiThread(executor,countDownLatch);

//只是爲了把線程加入到線程池

StaticMutiThread.Runner runner = staticMutiThread.new Runner();

runner.runit(staticMutiThread);

}

//運行直到關閉

countDownLatch.await();

executor.shutdown();

}

}

這段程序中生成了多個實例(多個this),若是在多個實例共有的靜態區上加鎖,能夠協調多個實例,若是隻在this上加上,則不行。

-----2014年3月17日

package com.zxg.test;


public  class StaticClassTest{


//若是在方法上加上synchronized 至關於:synchronized (StaticClassTest.class) 

//若是一個sync*方法鎖住了一個方法沒有釋放鎖,就會影響到其餘方法。

//好比網絡sync*方法中有網絡鏈接,慢速攻擊?

public static   synchronized   void pring_1(){

int i=10;

while(i>0){

System.out.println("---(1)-->"+i);

try {

Thread.currentThread().sleep(10L);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

i--;

}

}

public static  void pring_2(){

synchronized (StaticClassTest.class) {

int i=10;

while(i>0){

System.out.println("---(2)-->"+i);

try {

Thread.currentThread().sleep(100L);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

i--;

}

}

}

public static void main(String args[]){

//test 1

new Thread(new Runnable(){


@Override

public void run() {

StaticClassTest.pring_2();

}

}).start();

//test 1

new Thread(new Runnable(){


@Override

public void run() {

StaticClassTest.pring_1();

}

}).start();

System.out.println("12312312");

}

}

相關文章
相關標籤/搜索