synchronized
是我们的同步的一种选择,加锁就要有对应的钥匙
这个钥匙分为 当前类对象
,当前class对象
, 第三方对象
synchronized
可以修饰 变量、方法
我们以方法举例可以有如下的几种情况:
- 修饰静态方法 , 这里默认的锁就是当前
类的class对象
public synchronized static void t0(){
// code
}
- 修饰非静态方法 , 这里默认的锁就是当前
类的实例对象
public synchronized void t1(){
// code
}
经过验证,总结如下:
我们只有两种锁,对象锁和Class锁,Class锁允许所有的Class相同的对象都拿到资源,对象锁就单纯的只有这个对象才能获取到锁。其中,静态都是 锁类的 class。其他的时候我们都是习惯于单纯的锁对象。
具体的验证代码如下:
public class MySynchronized {
public int id;
public String name;
public Object o = new Object();
public synchronized static void t0(){
System.out.println(Thread.currentThread().getName()+" invoked "+" static t0 method start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" invoked "+" static t0 method end");
System.out.println();
}
public synchronized void t1() {
System.out.println(Thread.currentThread().getName()+" invoked "+"t1 start");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" invoked "+"t1 end");
System.out.println();
}
public void t2() {
synchronized (o) {
System.out.println(Thread.currentThread().getName()+" invoked "+"t2 start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" invoked "+"t2 end");
System.out.println();
}
}
public void t3() {
synchronized (o.getClass()) {
System.out.println(Thread.currentThread().getName()+" invoked "+"t3 start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" invoked "+"t3 end");
System.out.println();
}
}
public static void main(String[] args) {
// TODO 同步方法测试
// 同一个实例对象,哪个线程先调哪个就先得
MySynchronized test1 = new MySynchronized();
Thread t1 = new Thread(test1::t1);
Thread t2 = new Thread(test1::t1);
// thread1.start();
// thread2.start();
// TODO 静态方法测试
// 锁的是class,同一个class 先到先得
Thread t3 = new Thread(MySynchronized::t0);
Thread t4 = new Thread(MySynchronized::t0);
Thread t5 = new Thread(MySynchronized::t0);
// t3.start();
// t4.start();
// t5.start();
// TODO 测试不同实例的 成员变量
System.out.println(new MySynchronized().o.equals(new MySynchronized().o));
MySynchronized temp1 = new MySynchronized();
MySynchronized temp2 = new MySynchronized();
Thread t6 = new Thread(temp1::t2);
Thread t7 = new Thread(temp2::t2);
// t6.start();
// t7.start();
// TODO 测试同实例 成员变量
Thread t8 = new Thread(temp2::t2);
// t7.start();
// t8.start();
// TODO 测试不同实例 成员变量.class
Thread t9 = new Thread(temp2::t3);
Thread t0 = new Thread(temp2::t3);
t0.start();
t9.start();
}
}