昨天看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");
}
}