同步对象

时间:2012-07-03 16:57:34

标签: java synchronized

我的代码很简单:

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被调用?是不是要等到同步对象解锁?对不起,如果我听起来很愚蠢,我只是感到困惑。

4 个答案:

答案 0 :(得分:11)

  

是不是要等到同步对象解锁?

锁定由线程保存,因此您要对其进行两次同步(在doSomething中第一次调用main的情况下)没关系,它在同一个线程上。如果另一个线程然后尝试在synchronized上输入objToSync块,那么其他线程将等待此线程释放其所有锁。< / p>

您的代码将执行此操作:

  1. 输入main
  2. 获取objToSync对象
  3. 上当前线程的锁定
  4. 输出“某事”
  5. 致电doSomething
  6. 获取objToSync
  7. 上当前主题的第二个锁定
  8. 输出“两件事”
  9. 释放objToSync
  10. 上当前主题的第二个锁
  11. doSomething
  12. 返回
  13. 输出“三件事”
  14. objToSync
  15. 上释放当前主题的第一个锁定
  16. 致电doSomething
  17. objToSync
  18. 上获取新锁(针对同一个帖子)
  19. 输出“两件事”
  20. 释放锁定
  21. doSomething
  22. 返回
  23. main
  24. 返回

    以下是使用两个线程的示例:

    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");
            }
        }
    }
    

    输出:

    Main thread acquiring lock
    Main thread has lock, spawning second thread
    Main thread has started second thread, sleeping a moment
    Second thread running, acquiring lock
    Main thread releasing lock
    Main thread sleeping again
    Second thread has lock, sleeping a moment
    Main thread waiting for second thread to complete
    Second thread releasing lock
    Second thread is done
    Main thread exiting

答案 1 :(得分:5)

锁是reentrant所以如果某个线程拥有锁,它可以根据该锁进入其他同步块。在你的情况下,你只有一个线程(主要),他正在做这样的事情

synchronized(objToSync){
    System.out.println("something one");                    
    synchronized(objToSync){
        System.out.println("something two");
    }
    System.out.println("something three");
}

答案 2 :(得分:2)

锁定是同一线程的重入。这意味着获得对象锁定的线程可以访问该对象以及该对象的任何其他同步方法(或示例中的原子语句)。一旦获得锁定,该线程就不需要再次获得锁定。

答案 3 :(得分:1)

这是因为你的程序只有一个主线程。