V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kerb15
V2EX  ›  Java

[提问] 不同线程的类如何锁住同一个对象

  •  1
     
  •   kerb15 · 2018-03-31 18:50:05 +08:00 · 2803 次点击
    这是一个创建于 2436 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习多线程的时候遇到一个问题。

    我用不同的线程类分别实例化了一个线程 thread1 和 thread2

    thread1 和 thread2 分别在各自的 run 方法中 synchronize 了一个静态对象,然后在 thread1 中调用了 wait 方法,在 thread2 中调用了 notify 方法,发现会报错 java.lang.IllegalMonitorStateException

    希望有大佬能够给小弟解答一二,非常感谢!

    下面是代码:

    public class MyThread extends Thread {
    
    	@Override
    	public void run() {
    		synchronized (Main.i) {
    			while (true) {
    				Main.i = Main.i + 1;
    				if (Main.i == 2) {
    					try {
    						Main.i.wait();
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}
    	}
    }
    
    public class MyThread2 extends Thread {
    
    	@Override
    	public void run() {
    		synchronized (Main.i) {
    			while (true) {
    				if (Main.i==2){
    					Main.i.notify();
    				}
    			}
    		}
    	}
    }
    
    public class Main {
    
    	public static volatile Integer i = 0;
    
    	public static void main(String[] args) {
    		MyThread myThread = new MyThread();
    		MyThread2 myThread2 = new MyThread2();
    		myThread.start();
    		myThread2.start();
    	}
    }
    
    8 条回复    2018-03-31 21:32:52 +08:00
    wwqgtxx
        1
    wwqgtxx  
       2018-03-31 18:57:44 +08:00   ❤️ 1
    你这里 Main.i = Main.i + 1;的时候 i 都已经不是同一个对象了好吧
    kerb15
        2
    kerb15  
    OP
       2018-03-31 18:59:11 +08:00
    @wwqgtxx 为什么不是同一个对象啊,它不是静态的吗
    lhx2008
        3
    lhx2008  
       2018-03-31 19:14:49 +08:00 via Android   ❤️ 1
    @kerb15 你下面自己把 main.i 改了,相当于重新新建了一个 main.i,赋值,因为 Integer 是不变对象
    iffi
        4
    iffi  
       2018-03-31 19:21:45 +08:00
    看了下 Integer 是 final。它们不是同一个对象
    ahmcscx
        5
    ahmcscx  
       2018-03-31 19:22:28 +08:00
    用 ReentrantLock
    XinLake
        6
    XinLake  
       2018-03-31 19:52:34 +08:00 via Android
    我记得官方文档里讲 synchronized 锁对象应该用尽量简单的,像 Object。
    Arsenal16
        7
    Arsenal16  
       2018-03-31 20:58:07 +08:00   ❤️ 1
    少年手边有《实战 Java 高并发程序设计》嘛?可以参见 2.8.4 错误的加锁这一节。
    kerb15
        8
    kerb15  
    OP
       2018-03-31 21:32:52 +08:00
    懂了,谢谢大家的热心指导!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   911 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 21:36 · PVG 05:36 · LAX 13:36 · JFK 16:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.