You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java同步机制三类典型场景技术问题咨询

Java同步机制三类场景问题解答

问题1:同步代码块与无同步方法的线程访问规则

  • 当某线程执行foo的synchronized(a)代码块时:
    其他线程可以正常调用goo方法,也能直接操作对象a。因为goo没有任何同步约束,也没有尝试获取a对象的锁,所以不会被synchronized(a)的锁阻塞。但这种情况会引发线程安全问题,比如goo读取a.size()时,可能正好赶上foo在执行add操作的中间状态,导致读到的大小不准确。
  • 反之,当线程通过无同步的goo操作a时:
    其他线程可以直接进入foo的synchronized(a)块。因为goo没有获取a的锁,所以a对象的锁处于未被持有的状态,其他线程能正常获取锁执行add操作。同样,这种场景下a的操作存在线程安全风险,读写没有互斥。

问题2:同步方法中wait与notifyAll的执行逻辑

当第一个线程执行到wait()时,会释放当前持有的this锁,进入等待状态;第二个线程此时能获取this锁进入foo方法,执行notifyAll()后,会唤醒所有等待this锁的线程(包括第一个线程)。

被唤醒的线程不会立刻继续执行,它会进入this锁的竞争队列,处于可运行状态但无法继续执行wait()之后的代码——直到当前持有this锁的第二个线程退出foo方法(不管是执行return还是走完整个方法),释放this锁后,被唤醒的线程才会参与锁的竞争,竞争成功后从wait()的位置继续执行后续操作。

问题3:通知lambda创建的线程b的几种方式

可以通过以下几种常见方式在goo方法中通知线程b:

  • 共享volatile标志位:
    在类A中定义一个volatile修饰的布尔变量,用于控制线程状态:
    class A implements Runnable {
        Thread b;
        private volatile boolean shouldStop = false; // volatile保证多线程可见性
    
        void foo(){
            b = new Thread(() -> {
                while(!shouldStop) {
                    // 执行lambda逻辑
                    // 可添加短暂休眠避免空转
                    try { Thread.sleep(100); } catch(InterruptedException e) { break; }
                }
            });
            b.start();
        }
    
        void goo(){
            shouldStop = true; // 通知线程停止
        }
    }
    
  • Object锁配合wait/notify:
    用一个共享对象作为锁,通过wait()/notify()实现线程间通信:
    class A implements Runnable {
        Thread b;
        private final Object lock = new Object();
        private boolean isNotified = false;
    
        void foo(){
            b = new Thread(() -> {
                synchronized(lock) {
                    try {
                        // 等待通知,用while避免虚假唤醒
                        while(!isNotified) {
                            lock.wait();
                        }
                        // 收到通知后执行后续逻辑
                    } catch(InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            });
            b.start();
        }
    
        void goo(){
            synchronized(lock) {
                isNotified = true;
                lock.notify(); // 唤醒等待的线程b
                // 或用notifyAll()唤醒所有等待该锁的线程
            }
        }
    }
    
  • 线程中断机制:
    调用线程的interrupt()方法设置中断标志,线程内部处理中断信号:
    class A implements Runnable {
        Thread b;
    
        void foo(){
            b = new Thread(() -> {
                try {
                    while(!Thread.currentThread().isInterrupted()) {
                        // 执行lambda逻辑
                        Thread.sleep(100); // 若线程在阻塞状态,中断会抛出异常
                    }
                } catch(InterruptedException e) {
                    // 捕获中断异常,结束线程
                    Thread.currentThread().interrupt(); // 保留中断标志
                }
            });
            b.start();
        }
    
        void goo(){
            b.interrupt(); // 发送中断信号通知线程
        }
    }
    

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:15:19