简体   繁体   中英

Locking with synchronized method on same instance

I'm running this code:

public class SyncMethods {

    public static void main(String... args) {
        new SyncMethods().syncMethodsInvoker();
    }

    public void syncMethodsInvoker() {

        System.out.println("inside syncMethodsInvoker()");

        Thread t1 = new SyncMethodThread(this);
        Thread t2 = new SyncMethodThread(this);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    synchronized void firstSyncMethod(String threadName) {

        System.out.format("begin firstSyncMethod() %s\n", threadName);

        for (int i = 0; i < 5; i++) {
            System.out.format("looping firstSyncMethod() %s #%s for object %s\n", threadName, i, this);
            try {
                this.wait(100);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("end firstSyncMethod() " + threadName);
    }

    private class SyncMethodThread extends Thread {

        final private SyncMethods sm;

        public SyncMethodThread(SyncMethods sm) {
            this.sm = sm;
        }

        @Override
        public void run() {
            System.out.format("inside run() %s, sm: %s\n", this.getName(), sm);
            sm.firstSyncMethod(this.getName());
        }
    }
}

And i'm getting this output:

inside syncMethodsInvoker()
inside run() Thread-0, sm: multithreading.SyncMethods@6189a0b9
inside run() Thread-1, sm: multithreading.SyncMethods@6189a0b9
begin firstSyncMethod() Thread-0
looping firstSyncMethod() Thread-0 #0 for object multithreading.SyncMethods@6189a0b9
begin firstSyncMethod() Thread-1
looping firstSyncMethod() Thread-1 #0 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #1 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #1 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #2 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #2 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #3 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #3 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #4 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #4 for object multithreading.SyncMethods@6189a0b9
end firstSyncMethod() Thread-1
end firstSyncMethod() Thread-0

As both threads are locking on the same instance I was expecting the looping to go something like this:

looping firstSyncMethod() Thread-0 #0 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #1 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #2 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #3 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-0 #4 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #0 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #1 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #2 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #3 for object multithreading.SyncMethods@6189a0b9
looping firstSyncMethod() Thread-1 #4 for object multithreading.SyncMethods@6189a0b9

What am I doing wrong here?

Because of this line this.wait(100); which causes the current thread to release the lock and wait for 100ms. So the other thread can acquire the lock.

Object.wait(long)

This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object . Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens: ...

Complementing the answer with erickson's comment on the question: If you want to retain the lock while "waiting" a bit, use Thread.sleep() (or TimeUnit.MILLIS.sleep() ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM