线程八锁问题--synchronize所在哪个对象?
synchronized 加在成员方法上,锁的是this 对象,对于调用者来说,锁的是同一个对象、谁先拿到锁谁先执行。
synchronized加载静态方法上,所的是类对象。静态方法类加载的时候就有了。同多个对象通用一把锁。
1、情况1
@Slf4j(topic = "c.Number")
/**
* synchronized:锁的是方法的调用者,
* 下面两个方法用的是同一把锁,谁先拿到锁谁先执行。
* synchronized 记在成员方法上,锁的是this 对象,对于调用者来说,锁的是同一个对象
*/
class Number{
public synchronized void a() {
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
//结果:12或者21
}
2、情况2
@Slf4j(topic = "c.Number")
/**
* synchronized:锁的是方法的调用者,
* 下面两个方法用的是同一把锁,谁先拿到锁谁先执行。
* synchronized 记在成员方法上,锁的是this 对象,对于调用者来说,锁的是同一个对象
*/
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
//1s后12,或 2 1s后 1
}
3、情况3
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
//没有锁,不是同步方法,不受锁的影响
public void c() {
log.debug("3");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
new Thread(()->{ n1.c(); }).start();
//可能的结果:
//3 1s后 12 ---第一个线程先进来获得锁。c方法不用争抢锁资源,直接执行
//32 1s后 1 ---第二个线程先进来获得锁,2和3的顺序无法保证。
//23 1s后 1 ---同上
//
}
4、情况4
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
//两个对象,两个调用者 两个锁 互不干扰
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n2.b(); }).start();
// 2 1s后 1
}
5、情况5
@Slf4j(topic = "c.Number")
class Number{
//synchronized在和静态方法上,锁的是类对象
public static synchronized void a() {
sleep(1);
log.debug("1");
}
//synchronized 在普通方法上 锁的是this对象
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
//2 1s后 1
// 因为两个的锁对象不同
}
6、情况6
@Slf4j(topic = "c.Number")
/**
* 两个方法都是static,类加载的时候就存在了。
* 调用的时候Number全局唯一,锁的是class
* 加了static 就和调用对象是几个没关系(同一把锁)。
*/
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public static synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
//:1s 后12, 或 2 1s后 1
}
7、情况7
@Slf4j(topic = "c.Number")
/**
* 两个方法两把锁,不互干扰
*/
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n2.b(); }).start();
//:2 1s 后 1
//两个锁,互不干扰
}
8、情况8
@Slf4j(topic = "c.Number")
/**
* synchronized 都在静态方法上,锁对象是一个
*/
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public static synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n2.b(); }).start();
//:1s 后12, 或 2 1s后 1
//同一把锁。互斥
}
本文来自博客园,作者:iyandongsheng,转载请注明原文链接:https://www.cnblogs.com/ieas/p/16736131.html