java synchronized 类锁和对象锁
随手笔记,如有不对还请大神们指正!
偶尔在java的笔试题中会碰见synchronized类锁和对象锁相关的题,所以今天写了个例子测试了下!
synchronized的用法:synchronized修饰方法和synchronized修饰代码块。
1. 对象锁:synchronized修饰非静态方法和代码块(this)
2. 类锁:synchronized修饰静态方法和代码块(*.class)
直接看代码:
/**
* OrderService 加锁方法类
*/
public class OrderService {
/**
* synchronized 放在非静态方法上
*/
public synchronized void getOrder1() {
System.out.println("getOrder1");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* synchronized 放在this上
*/
public void getOrder2() {
synchronized(this){
System.out.println("getOrder2");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* synchronized 放在静态方法上
*/
public static synchronized void getOrder3() {
System.out.println("getOrder3");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* synchronized 放在class上
*/
public void getOrder4() {
synchronized(OrderService.class){
System.out.println("getOrder4");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* SycnTest1 线程1 :run方法调用OrderService中的方法
*/
public class SycnTest1 implements Runnable {
private OrderService os ;
public SycnTest1(OrderService os) {
this.os = os;
}
public void run() {
os.getOrder1();
}
}
/**
* SycnTest2 线程1 :run方法调用OrderService中的方法
*/
public class SycnTest2 implements Runnable {
private OrderService os ;
public SycnTest2(OrderService os) {
this.os = os;
}
public void run() {
os.getOrder2();
}
}
/**
* MainTest main方法入口
* 主要开了2个线程来执行OrderService中的方法
*/
public class MainTest {
public static void main(String[] args) {
OrderService os = new OrderService();
(new Thread(new SycnTest1(os))).start();
(new Thread(new SycnTest2(os))).start();
}
}
执行结果分析:
1.代码中SycnTest1的run方法调用getOrder1()
代码中SycnTest2的run方法调用getOrder2()
此时执行结果是同步执行:
可能结果a:先打印getOrder1 间隔10秒在打印getOrder2
可能结果b:先打印getOrder2 间隔5秒在打印getOrder1
由此可见:getOrder1()中的synchronized 作用在非静态方法上和getOrder2()中的synchronized代码块是作用到this上是一样的,锁住的是当前的对象,所以结果是同步执行
2.代码中SycnTest1的run方法调用getOrder3()
代码中SycnTest2的run方法调用getOrder4()
此时执行结果是同步执行:
结果a:先打印getOrder3 间隔10秒在打印getOrde4
结果b:先打印getOrder4 间隔5秒在打印getOrder3
由此可见:getOrder3()中的synchronized 作用在静态方法上和getOrder4()中的synchronized代码块是作用到class上是一样的,锁住的是当前的类,所以结果是同步执行
3.代码中SycnTest1的run方法调用getOrder1()
代码中SycnTest2的run方法调用getOrder4()
此时执行结果是异步执行:
结果a:先打印getOrder1,接着 再打印getOrde3
结果b:先打印getOrder3,接着 再打印getOrde1
由此可见:getOrder1()中的synchronized 作用在非静态方法上和getOrder3()中的synchronized代码块是作用到静态方法上,一个锁住的是当前对象,一个锁住的是当前的类,所以结果是几乎一同打印,但是谁在钱谁在后就不一定了。