我们可以同时从多个线程访问同一个实例的同步方法和非同步方法吗?

时间:2018-07-29 16:46:21

标签: java multithreading synchronization java-threads

这似乎是一个非常幼稚的问题,但我在任何地方都找不到任何具体答案。我什至在实践中都尝试过,但是由于我们无法预测Java中线程资源分配的行为,因此很难确定。 我只想知道是否可以从该类的同一实例的两个不同线程中同时访问该类的同步方法和非同步方法?

1 个答案:

答案 0 :(得分:2)

看不到任何问题。试试这个:

public class Main {

    public static final SyncNotsynced sn = new SyncNotsynced();

    public static void main(String[] args){
        Thread t1 = new Thread(sn::synced);
        Thread t2 = new Thread(sn::notsynced);
        t1.start();
        t2.start();
    }

    public static class SyncNotsynced {

        public synchronized void synced(){
            System.out.println(Thread.currentThread().getName() + " enter synced");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println(Thread.currentThread().getName() +  " exit synced");
        }

        public void notsynced(){
            System.out.println(Thread.currentThread().getName() + " enter notsynced");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println(Thread.currentThread().getName() +  " exit notsynced");
        }
    }
}

或查看live example :)。如您所见,进入Thread 1Thread 2都在退出之前发生:

Thread-0 enter synced
Thread-1 enter notsynced
Thread-0 exit synced
Thread-1 exit notsynced

有关正式解释,您可以阅读JLS 17,但总而言之,只有一个线程可以在同一对象监视器上输入同步块。

顺便说一句,我使用了Thread.sleep because(强调我的意思):

  

Thread.sleep导致当前正在执行的线程进入睡眠状态   (暂时停止执行)在指定的期限内,具体取决于   系统计时器和调度程序的精度和准确性。 线程    不会丢失任何监视器的所有权 ,并且恢复执行   取决于调度和处理器的可用性,   执行线程。