java synchronize锁

来源:互联网 发布:网络语狗子是啥意思 编辑:程序博客网 时间:2024/05/21 14:03

一、先来看看作用域

这是一个线程类,run方法上面加上了synchronize关键字,目的是为了测试方法上面加锁作用的范围是这个实例还是整个类

public class SynchronizedThread implements Runnable{private String name;public SynchronizedThread(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic synchronized void run() {System.out.println(name+" before");try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(name+" after");}}


下面是测试类
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();//开启10个线程让它跑,看看synchronized关键字放在方法上是对于对象有用还是对于类有用for(int i =0;i<10;i++){executorService.submit(new SynchronizedThread(i+""));}executorService.shutdown();}}

结果如下:

0 before
3 before
2 before
4 before
7 before
8 before
6 before
1 before
5 before
9 before
6 after
8 after
3 after
7 after
4 after
0 after
2 after
1 after
9 after
5 after

说明在一个实例调用run方法的同时,另一个实例也会调用run()方法

结论:synchronize关键字放在方法的前面,作用域是单个实例


下面来看synchronize(obj)的情况(同步代码块)

public  class SynchronizedThread implements Runnable{private String name;public SynchronizedThread(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic  void run() {synchronized (name) {System.out.println("before");try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("this is my name "+name);}}}

测试类还是一样,


结果如下:

before
before
before
before
before
before
before
before
before
before
this is my name 3
this is my name 7
this is my name 2
this is my name 6
this is my name 0
this is my name 1
this is my name 4
this is my name 9
this is my name 5
this is my name 8


结论:synchronize(obj)是获得这个对象实例的锁,同一时间只能有一个方法块去操作这个实例,注意,我以上的测试全部都是排除作用域是类的情况,而并没有对实例的情况作为证明,想要证明的可以自己写测试方法证明,我这里仅仅排除了作用域为类而已


如果上面的synchronize(name)里面的name 改成this,那么作用域就是整个实例了



给静态方法加同步锁如下:

public class SynchronizedThread implements Runnable{private String name;public SynchronizedThread(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic  void run() {test();try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("after");}public synchronized static  void test(){System.out.println("this is a test!");}}

this is a test!
this is a test!
this is a test!
this is a test!
this is a test!
this is a test!
this is a test!
this is a test!
this is a test!
this is a test!
after
after
after
after
after
after
after
after
after
after

可以看出作用域是实例



下面是同步代码块锁住类:

public class SynchronizedThread implements Runnable{private String name;public SynchronizedThread(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic  void run() {synchronized (SynchronizedThread.class) {System.out.println("this is a test");try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("after");}}}

this is a test
after
this is a test
after
this is a test
after
this is a test
after
this is a test
after
this is a test
after
this is a test
after
this is a test
after
this is a test
after
this is a test
after

结论:采用synchronize(xxx.class)的方式,作用域是整个类