两个同步方法是否同时执行

发布于 2024-09-07 11:54:28 字数 355 浏览 2 评论 0原文

我在一个类中有 4 个方法(m1m2m3m4)。方法m1m2m3同步方法。另外,我分别有 4 个线程 t1t2t3t4

如果t1访问m1方法(同步方法),t2线程是否可以同时访问m2方法(同步方法) ?如果不是的话t2会是什么状态?

I have 4 methods (m1, m2, m3 and m4) in a class. Method m1, m2 and m3 are synchronized methods. Also, I have 4 threads t1, t2, t3 and t4 respectively.

If t1 access the m1 method (synchronized method), could t2 thread access m2 method (synchronized method) simultaneously? If not what would be the state of t2?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

和影子一齐双人舞 2024-09-14 11:54:28

如果t1访问m1方法(同步方法),t2线程是否可以同时访问m2方法(同步方法)?

synchronized 关键字适用于对象级别,并且只有一个线程可以持有该对象的锁。所以只要你说的是同一个对象,那么t2会等待t1释放它进入时获取的锁m1

然而,线程可以通过调用Object.wait()来释放锁,而不从该方法返回。

如果不是,t2 的状态会是什么?

它将等待 t1 释放锁(从方法返回或调用 Object.wait ())。具体来说,它将位于 阻塞状态

阻塞等待监视器锁的线程的线程状态。处于阻塞状态的线程正在等待监视器锁进入同步块/方法,或者在调用Object.wait后重新进入同步块/方法。

示例代码:< /strong>

public class Test {

    public synchronized void m1() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public synchronized void m2() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public static void main(String[] args) throws InterruptedException {
        final Test t = new Test();
        Thread t1 = new Thread() { public void run() { t.m1(); } };
        Thread t2 = new Thread() { public void run() { t.m2(); } };

        t1.start();
        Thread.sleep(500);

        t2.start();
        Thread.sleep(500);

        System.out.println(t2.getState());
    }
}

输出:

BLOCKED

If t1 access the m1 method (synchronized method), could t2 thread access m2 method (synchronized method) simultaneously?

The synchronized keyword applies on object level, and only one thread can hold the lock of the object. So as long as you're talking about the same object, then no, t2 will wait for t1 to release the lock acquired when it entered m1.

The thread can however release the lock without returning from the method, by calling Object.wait().

If not, what would be the state of t2 ?

It would sit tight and wait for t1 to release the lock (return from the method or invoke Object.wait()). Specifically, it will be in a BLOCKED state.

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

Sample code:

public class Test {

    public synchronized void m1() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public synchronized void m2() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public static void main(String[] args) throws InterruptedException {
        final Test t = new Test();
        Thread t1 = new Thread() { public void run() { t.m1(); } };
        Thread t2 = new Thread() { public void run() { t.m2(); } };

        t1.start();
        Thread.sleep(500);

        t2.start();
        Thread.sleep(500);

        System.out.println(t2.getState());
    }
}

Output:

BLOCKED
子栖 2024-09-14 11:54:28

如果这些方法在同一监视器上同步,则它们不能在不同线程中同时执行。当第二个线程到达监视器入口(在本例中是同步方法的开始)时,它将阻塞,直到第一个线程释放监视器。

在这种情况下,由 jconsole 报告的被阻塞线程的实际状态将类似于 java.lang.Thread.State: WAITING (on object Monitor)

假设所有方法都是普通实例方法,那么在同一对象上调用时它们将共享同一监视器。也就是说,如果您有类似的内容:

// Thread 1
A a1 = new A();
a1.m1();

// Thread 2
A a2 = new A();
a2.m2()

那么在这种情况下,第二个线程将能够调用该方法,因为它试图获取 a2 对象的隐式监视器,即 未被线程 1 锁定。但是,如果线程 2 尝试调用 a1.m2(),那么它将阻塞,直到线程 1 完成执行 m1()

如果您有静态方法,那么它们将获得类本身的显式监视器(在我假设的命名情况下为 A.class),因此不会被任何实例阻止方法调用。

If the methods are synchronized on the same monitor, then they cannot execute simultaneously in different threads. When the second thread comes to the monitor entry (the start of the synchronized method in this case), it will block until the first thread releases the monitor.

The actual state of the blocked thread in this case, as reported by jconsole, will be something like java.lang.Thread.State: WAITING (on object monitor)

Assuming all methods are normal instance methods, then they will share the same monitor when invoked on the same object. That is, if you had something like:

// Thread 1
A a1 = new A();
a1.m1();

// Thread 2
A a2 = new A();
a2.m2()

then in this case, the second thread will be able to call the method, because it's trying to obtain the implicit monitor of the a2 object, which is not locked by thread 1. But if thread 2 tried to call a1.m2(), then it would block until thread 1 had finished executing m1().

If you have static methods, then they obtain the explicit monitor of the class itself (A.class in my hypothetical-naming case), so will not be blocked by any instance method invocations.

掩于岁月 2024-09-14 11:54:28

不,不可能。这是同步的唯一一点:不同的线程不能同时做这些事情(你不必防止同一个线程同时做这些事情,因为单个线程不能做任何事情完全并行。)等待线程的状态是“等待锁定”。 (使用足够现代的 JVM,如果您以正确的方式询问,实际上可以在控制台上显示此状态。)

No, it couldn't. That's the only point there is to synchronized: different threads can't do these things simultaneously (You don't have to guard against the same thread doing them simultaneously, because a single thread can't do anything in parallel at all.) The state of the waiting thread is 'waiting for lock'. (With a sufficiently modern JVM you can actually have this state displayed on the console if you ask in the right way.)

习ぎ惯性依靠 2024-09-14 11:54:28

如果t1访问m1方法(同步方法),t2线程是否可以同时访问m2方法(同步方法)?

不会。线程 t2 将等待线程 t1 释放锁。
在同一个示例中,t2 可以访问未同步的方法 m4。

锁定同步方法

每个对象都有一个与其关联的内在锁。按照惯例,需要对对象字段进行独占和一致访问的线程必须在访问对象字段之前获取对象的内在锁,然后在访问完毕后释放内在锁

当线程调用同步方法时,它会自动获取该方法对象的内在锁,并在该方法返回时释放它。即使返回是由未捕获的异常引起的,也会发生锁释放

回到第二个查询:

如果不是,t2 的状态会是什么?

线程 t2 处于阻塞状态并等待线程 t1 释放锁。

来自java文档页面:

使同步 方法有两个作用。

首先,同一对象上的同步方法的两次调用不可能交错。当一个线程正在执行对象的同步方法时,调用同一对象的同步方法的所有其他线程都会阻塞(挂起执行),直到第一个线程完成该对象。

其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立发生之前关系。这保证了对象状态的更改对所有线程都可见

If t1 access the m1 method (synchronized method), could t2 thread access m2 method (synchronized method) simultaneously?

No. Thread t2 will wait for Thread t1 to release the lock.
In your same example, t2 can access method m4 which is not synchronized.

Locks In synchronized Methods

Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them

When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception

Coming back to your second query:

If not, what would be the state of t2 ?

Thread t2 is in blocked state and waiting for Thread t1 to release the lock.

From java documentation page:

making synchronized method have two effects.

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all thread

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文