线程八锁问题--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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现