首页 新闻 会员 周边

将线程对象作为锁:synchronized (b),这是锁住什么呀

0
[待解决问题]
class ThreadA {
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        System.out.println("b is start....");
        synchronized (b)//括号里的b是什么意思,起什么作用,b作为对象锁,是锁住b线程的synchronized中代码还是主线程synchronized中代码? <1>
        {
            try {

                System.out.println("Waiting for b to complete...");
                b.wait();//这一句是什么意思,究竟让谁wait?
                System.out.println("Completed.Now back to main thread");
            } catch (InterruptedException e) {
            }
        }
        System.out.println("Total is :" + b.total);
    }
}


class ThreadB extends Thread {
    int total;

    public void run() {
       /* try {
        }catch(Exception ex){}*/
        synchronized (this)     //<2>
        {

            System.out.println("ThreadB is running..");
            for (int i = 0; i < 10; i++) {
                total += i;
                System.out.println("total is " + total);
            }
            notify();
        }
    }
}

将线程对象作为锁:synchronized (b),这是锁住什么呀,主线程要b线程对象锁有什么 用?

这段代码,为什么一直是 System.out.println("b is start...."); 执行后,接着就是b线程执行...不断尝试,不知道为什么没有wait阻塞现象?

fangpengcheng_方鹏程的主页 fangpengcheng_方鹏程 | 初学一级 | 园豆:4
提问于:2020-09-25 21:58
< >
分享
所有回答(2)
0

...奇怪的描述,..我这里很明显的wait了。。

正常情况下,B和A都是去拿B的对象锁,B先执行的,等B执行完,才会到A,那A会一直wait,没有人去notify它了。。

//这是打印的输出,明显A那后面没输出了啊。。。
//话说这是想测试wait是不是会释放锁吗。。
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
total is 15
total is 21
total is 28
total is 36
total is 45
b is start....
Waiting for b to complete...
WMG-Eight | 园豆:973 (小虾三级) | 2020-09-27 09:26
0
  1. synchronized (b) 是用 b 这个对象作为锁,ThreadB 中的 synchronized (this) 是以调用 run() 这个方法的当前对象作为锁,所以这两个同步代码是一个锁,会存在竞争关系。
  2. 主线程要 synchronized(b) {...} 是因为这个同步代码块里面调用了 b.wait();,JVM 要求调用了 b 对象的 wait() 方法需要在以 b 对象锁的 synchronized 同步代码中。
  3. 执行了 b.start(); 之后,如果 main 方法先获得了 synchronized 锁,然后会执行 b.wait(),b.wait() 会使当前执行 b.wait() 的线程阻塞,即执行 main 方法的线程会阻塞,而 b 线程不会阻塞,所以 b.wait() 是让出当前线程所占用的锁,然后 b 线程获取了锁,就去执行 run 方法里面的循环逻辑,等 b 线程执行后,main 方法中阻塞的 synchronized 锁就自动被唤醒(Object 类中的 join 方法依据这个原理,参考:https://blog.csdn.net/notOnlyRush/article/details/90670541),然后 main 方法中的主线程接着从刚刚调用 b.wait() 的地方继续执行。
  4. 执行了 b.start(); 之后,如果 b 线程对象中的 run 方法先获得了锁,那么限制性 run 方法中的循环逻辑,接着 main 方法中的 synchronized 同步块获得了锁,再执行 b.wait() 时,会阻塞,因为没有唤醒操作,所以会一直阻塞。
唯学而知 | 园豆:186 (初学一级) | 2021-07-27 19:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册