synchronize作用范围
synchronized 解决的三种方式:
1)使用synchronized 代码块
2)synchronized 同步方法
3)synchronized 同步静态
使用synchronize代码块通过指定锁来制定作用范围 :
1. 以this充当锁 是以对象作为锁 锁整个对象
2. 以x.class 作为锁 是以整个类为锁 锁此类的所有对象
使用 synchronized 同步(静态)方法 有几种不同的情况
1. 普通方法与同步(包括静态)方法互补相关
2. synchronized 方法默认以this为锁 也就是锁整个对象
3. synchronized 静态方法默认以class为锁 也就是锁整个类
4. 同步静态方法与普通同步方法之间互不干扰 (内存区域不同)
同一对象普通同步方法
运行结果是 先等待3s后再输出 说明锁了整个对象
//测试方法
public static void main(String[] args) throws InterruptedException {
TestNomalSynchronize testNomalSynchronize = new TestNomalSynchronize();
new Thread(()->{
try {
testNomalSynchronize.test1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Thread.sleep(1000);
new Thread(()->{
try {
testNomalSynchronize.test2();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
//普通的synchronized锁对象 调用方法是将整个对象锁住 相当于将两个方法缩到了一起
//静态锁锁的是类 (不同对象之间也会锁住)
class TestNomalSynchronize{
public synchronized void test1() throws InterruptedException {
Thread.sleep(3000);
System.out.println("test1");
}
public synchronized void test2(){
System.out.println("test2");
}
}
不同对象普通同步方法
运行结果 : 先输出test2 过2s输出test1 说明不同对象间没有同步
public static void main(String[] args) throws InterruptedException {
//测试不同对象 不会锁到一起
TestNomalSynchronize testNomalSynchronize = new TestNomalSynchronize();
TestNomalSynchronize testNomalSynchronize1 = new TestNomalSynchronize();
new Thread(()->{
try {
testNomalSynchronize.test1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Thread.sleep(1000);
new Thread(()->{
try {
testNomalSynchronize1.test2();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
同一个(不同)对象的静态同步方法和普通同步方法 (是不是同一个对象对静态方法不影响)
运行结果 : 先输出test2 过2s输出test1 说明静态同步方法和普通同步方法间没有同步
public static void main(String[] args) throws InterruptedException {
//一个对象有静态有非静态同步方法没有锁住整个类
//静态方法在静态池中 普通同步/普通方法在对象中所以不能同步整个类
TestStaticSynchronize staticSynchronize1 = new TestStaticSynchronize();
new Thread(()->{
try {
TestStaticSynchronize.test1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Thread.sleep(1000);
new Thread(()->{
try {
staticSynchronize1.test2();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
class TestStaticSynchronize{
public static synchronized void test1() throws InterruptedException {
Thread.sleep(3000);
System.out.println("test1");
}
public synchronized void test2(){
System.out.println("test2");
}
}
class TestStaticSynchronize1{
public static synchronized void test1() throws InterruptedException {
System.out.println("test1");
}
public synchronized void test2(){
System.out.println("test2");
}
public synchronized static void test3() throws InterruptedException {
Thread.sleep(3000);
System.out.println("test3");
}
}
同一个(不同)对象的两个静态方法
运行结果 : 等待3s 运行test1和test2 说明两个静态方法之间是同步的
public static void main(String[] args) throws InterruptedException {
//同类的静态方法能同步锁
new Thread(()->{
try {
TestStaticSynchronize1.test3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Thread.sleep(1000);
new Thread(()->{
try {
TestStaticSynchronize1.test1();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}