为什么要声明此方法已同步?

问题描述 投票:1回答:1

考虑这个课程:

// Synchronizing access to shared mutable data using Object 
// methods wait and notifyAll.
public class SynchronizedBuffer implements Buffer
{
    private int buffer = -1; // shared by producer and consumer threads
    private boolean occupied = false;

    // place value into buffer
    public synchronized void blockingPut(int value) throws InterruptedException
    {
        // while there are no empty locations, place thread in waiting state
        while (occupied) 
        {
            // output thread information and buffer information, then wait
            System.out.println("Producer tries to write."); // for demo only
            displayState("Buffer full. Producer waits."); // for demo only
            wait();
        }

        buffer = value; // set new buffer value

        // indicate producer cannot store another value
        // until consumer retrieves current buffer value
        occupied = true;

        displayState("Producer writes " + buffer); // for demo only

        notifyAll(); // tell waiting thread(s) to enter runnable state
    } // end method blockingPut; releases lock on SynchronizedBuffer 

    // return value from buffer
    public synchronized int blockingGet() throws InterruptedException
    {
        // while no data to read, place thread in waiting state
        while (!occupied)
        {
            // output thread information and buffer information, then wait
            System.out.println("Consumer tries to read."); // for demo only
            displayState("Buffer empty. Consumer waits."); // for demo only
            wait();
        }

        // indicate that producer can store another value 
        // because consumer just retrieved buffer value
        occupied = false;

        displayState("Consumer reads " + buffer); // for demo only

        notifyAll(); // tell waiting thread(s) to enter runnable state

        return buffer;
    } // end method blockingGet; releases lock on SynchronizedBuffer 

    // display current operation and buffer state; for demo only
    private synchronized void displayState(String operation)
    {
        System.out.printf("%-40s%d\t\t%b%n%n", operation, buffer, occupied);
    } 
} // end class SynchronizedBuffer

以及本书中的这一段:

请注意,方法displayState是同步方法。这很重要,因为它也读取SynchronizedBuffer的共享可变数据。尽管一次仅一个线程可以获取给定对象的锁,但是一个线程可以多次获取同一对象的锁-这被称为可重入锁,并使一个同步方法可以在同一对象上调用另一个对象。] >

为什么我们只将displayState()方法声明为同步方法,尽管仅从同步方法中调用它,因此,当调用该方法时,调用线程已经在对象上拥有了监视器锁定?

考虑此类://使用对象//方法同步访问共享的可变数据,并等待和notifyAll。公共类SynchronizedBuffer实现Buffer {private int buffer = -1; // ...

java concurrency
1个回答
0
投票

您在质疑此源代码是正确的。当某个方法拥有对象的监视器时,再次输入synchronized方法或阻止获取同一监视器将完全无效。

© www.soinside.com 2019 - 2024. All rights reserved.