Synchronized 是对类的方法或者方法块进行加锁,防止其余的线程同时访问同一个方法或者方法块。Synchronized的作用域有两种:
第一种是对方法进行加锁。方法的加锁可以分为非静态加锁和静态加锁:Synchronized method() 和 static synchronizedmethod()。非静态加锁时,防止其它线程同时访问当前类的当前实例的synchronized方法(注意:如果是当前类的不同实例是可以同时访问synchronized的方法的)。静态加锁时,是防止该类的所有实例同时访问method()方法。测试代码如下:
public class Test extends Thread{
public static synchronized void method(){
try {
System.out.println("method");
sleep(2000);
} catch (Exception e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
public void run(){
method();
}
public static void main(String[] args){
ExecutorService pool = Executors.newCachedThreadPool();
for(int count=0;i<count;i++){
Test t = new Test();
pool.execute(t);
}
}
}
这个示例可以得出static synchronized 和synchronized的区别。
第二种 是对方法快进行加锁。在方法体内用synchronized(Object)这个方法可以对方法体内的块进行加锁,注意:括号内的必须是一个对象,意思是说不同的线程之间谁先拿到object这个对象,谁就应该先进入方法内执行,执行完后释放对象。其中synchronized(this)这个方法的加锁表示的是对当前类的当前实例的对应方法加锁,类似于synchronized method()这个方法的作用。如果想让类的所有实例都能够达到线程同步的作用,那么有两种方法可以解决:
1. 使用synchronized(xxx.Class)其中xxx表示当前类的类名,这个的作用就类似于static synchronized method()的作用。
2. 给synchronized(key)设置个key值,可以将key值设置为: Stringfinal static key = “”;这样的对象形式,要保证每次取得的key值都是一样的,这样锁才能够取得作用,不然的话因为key值每次都不一样,导致synchronized失效。
测试的代码如下:
package test;
importjava.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestField extends Thread {
privateString key = "";
publicvoid run() {
for(int count = 0; count < 5; count++) {
synchronized(TestField.class) {
try{
System.out.println(Thread.currentThread().getName()
+"method1");
sleep(1000);
}catch (Exception e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
publicstatic void main(String[] args) {
ExecutorServicepool = Executors.newCachedThreadPool();
for(int count = 0; count < 10; count++) {
TestFieldtf = new TestField();
pool.execute(tf);
}
}
}