尽管对象被锁定,但未同步的方法仍然可以访问,为什么?

An unsynchronized method can still get access despite the object being locked, why?

考虑以下因素:

    class A {
    public static void main(String[] args) throws InterruptedException
    {
        final A a = new A();
        new Thread()
        {
            public void run()
            {
                a.intrudeLock();
            };
        }.start();
        Thread.sleep(1000);
        new Thread()
        {
            public void run()
            {
                a.doSomethingAfterLocking();
            };
        }.start();
    }

    synchronized void doSomethingAfterLocking() throws InterruptedException
    {
        System.out.println("aquired lock");
        Thread.sleep(10000);
        System.out.println("finished stuff");
    }

    void intrudeLock()
    {
        System.out.println("don't need object's lock");
    }
}

通过锁定机制 - 预期输出是(至少在大多数情况下):

aquired lock
don't need object's lock
finished stuff

我不是在问为什么这个输出,并且理解第二个线程不需要为其方法调用锁定并因此可以入侵的原因。
现在这是我的疑问 - 当一个线程获取锁时,它的意图是获得对该对象的排他性并且直观地执行环境应该防止其他线程改变任何状态。但这不是 Java 实现它的方式。有没有这样设计这个机制的原因?

When a thread acquires lock, its intention is gaining exclusivity over the object and intuitively the execution environment should prevent any state change by other threads. .

小修正:

When a thread acquires lock, its intention is gaining exclusivity over the monitor of the object and intuitively the execution environment should prevent any state change by other threads which are waiting (which need) to acquire the same lock.*

完全留给程序员来指定他是否希望某些字段/资源仅在获取锁后使用。如果你有一个字段只能被一个线程访问,那么它不需要同步(获取锁)。

必须注意的重点是,完全由程序员根据程序中的代码路径来同步访问字段。例如,一个字段可以由一个代码路径(需要同步)中的多个线程访问,而在另一路径中只能由一个线程访问。但是由于很有可能两个代码路径可以被不同的线程同时访问,所以你应该在进入上述任何代码路径之前获取锁。

现在,JIT 可能会决定忽略您的锁定请求 (lock-elision),如果它认为它们是不必要的(比如尝试锁定永远不会逃脱的方法本地字段) .