我有简单的代码:

public class testing {
    private static Object objToSync = new Object();

    public static void main(String[] args) {
        String obj1 = null;
        synchronized(objToSync){
            System.out.println("something one");
            doSomething();
            System.out.println("something three ");
        }

        doSomething();
    }

    private static void doSomething() {
        synchronized(objToSync){
            System.out.println("something two");
        }
    }


我读过几件事,但仍然对此感到困惑。为什么要调用主体中的doSomething?是否不应该等待同步对象被解锁?对不起,如果我听起来很愚蠢,我很困惑。

最佳答案

是否不应该等待同步对象被解锁?


该锁由线程持有,因此您对其进行两次同步(在doSomething中第一次调用main的情况下)这一事实无关紧要,因为它在同一线程上。如果另一个线程然后尝试在synchronized上输入一个objToSync块,则另一个线程将等待,直到该线程释放了所有锁。

您的代码将执行以下操作:


输入main
获取objToSync对象上当前线程的锁
输出“某物”
致电doSomething
objToSync上的当前线程获取第二个锁
输出“两个东西”
释放objToSync上当前线程的第二个锁
doSomething返回
输出“三件事”
释放objToSync上当前线程的第一个锁
致电doSomething
objToSync上获取一个新锁(用于同一线程)
输出“两个东西”
释放那个锁
doSomething返回
main返回


这是一个使用两个线程的示例:

public class SyncExample {

    private static Object objToSync = new Object();

    public static final void main(String[] args) {
        Thread second;

        System.out.println("Main thread acquiring lock");
        synchronized (objToSync) {
            System.out.println("Main thread has lock, spawning second thread");
            second = new Thread(new MyRunnable());
            second.start();
            System.out.println("Main thread has started second thread, sleeping a moment");
            try {
                Thread.currentThread().sleep(250);
            }
            catch (Exception e) {
            }
            System.out.println("Main thread releasing lock");
        }
        System.out.println("Main thread sleeping again");
        try {
            Thread.currentThread().sleep(250);
        }
        catch (Exception e) {
        }
        System.out.println("Main thread waiting for second thread to complete");
        try {
            second.join();
        }
        catch (Exception e) {
        }
        System.out.println("Main thread exiting");
    }

    static class MyRunnable implements Runnable {

        public void run() {
            System.out.println("Second thread running, acquiring lock");
            synchronized (objToSync) {
                System.out.println("Second thread has lock, sleeping a moment");
                try {
                    Thread.currentThread().sleep(250);
                }
                catch (Exception e) {
                }
                System.out.println("Second thread releasing lock");
            }
            System.out.println("Second thread is done");
        }
    }
}


输出:

主线程获取锁
主线程有锁,产生第二个线程
主线程已启动第二个线程,正在休眠
第二线程运行,获取锁
主螺纹释放锁
主线程再次入睡
第二线程有锁,睡一会儿
主线程等待第二个线程完成
第二线程释放锁
第二个线程完成
主线程退出

07-26 08:50