Synchronized 使用方式
修饰到方法上
以下的m1\m2方法上加锁相当于,把锁加在this对象上,所以只有m1下城执行完成m2线程才可以继续执行
public class T1 {
private static synchronized void m1() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
System.out.println("m1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static synchronized void m2() {
System.out.println("m2");
}
public static void main(String[] args) {
new Thread(T1::m1, "m1").start();
new Thread(T1::m2, "m2").start();
}
}
修饰到对象上
下面的示例是启动两个线程进行对count字段--,一个加锁一个不加锁,最后的结果没有得到预期的效果【按照顺序进行递减】,是因为两个线程在并行执行都可以访问到count字段,所以没得到预期的效果。
public class T2 {
private static int count = 10;
private static final Object o = new Object();
private static void m1() {
synchronized (o) {
m3();
}
}
private static void m2() {
m3();
}
private static void m3() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
count--;
System.out.println(Thread.currentThread().getName() + " count: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Thread(T2::m1, "m1").start();
new Thread(T2::m2, "m2").start();
}
}
如果要达到预期的效果两个线程同时对操作方法加锁
public class T2 {
private static int count = 10;
private static final Object o = new Object();
private static void m1() {
synchronized (o) {
m3();
}
}
private static void m2() {
synchronized (o) {
m3();
}
}
private static void m3() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
count--;
System.out.println(Thread.currentThread().getName() + " count: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Thread(T2::m1, "m1").start();
new Thread(T2::m2, "m2").start();
}
}
其实synchronized还可以修饰T.class,本质上synchronized修饰的就是一个实例
从以上的例子来看,synchronized 修饰的是一个实例,锁在java对象中的体现是在,对象头里jvm中采用两个字节来存储对象头,具体是怎么实现的需要阅读代码和查看java对象的字节码在jvm的存储方式.

本文详细解读了synchronized在Java中的两种使用方式:方法锁(this对象锁)和对象锁。通过实例演示了如何确保线程同步,以及对象头中锁机制的工作原理。重点讨论了如何在并发编程中正确应用synchronized以达成预期效果。
2万+

被折叠的 条评论
为什么被折叠?



