【问题标题】:How does it seem to appear that another thread is able to acquire the lock while one thread having the same lock is sleeping?当具有相同锁的一个线程正在休眠时,另一个线程似乎能够获得锁?
【发布时间】:2017-11-15 21:48:11
【问题描述】:

下面的代码 - 没有 wait() 和 notify() 方法:

package com.jay;

import java.util.Random;

public class Main {

    public static void main(String[] args) {
        Message message = new Message();
        (new Thread(new Writer(message))).start();
        (new Thread(new Reader(message))).start();
    }

}

class Message {
    private String message;
    private boolean empty = true;

    public synchronized String read() {
        while (empty) {

        }
        empty = true;
        return message;
    }

    public synchronized void write(String message) {
        while (!empty) {

        }
        empty = false;
        this.message = message;
    }
}

class Writer implements Runnable {
    private Message message;

    public Writer(Message message) {
        this.message = message;
    }

    public void run() {
        String[] messages = {
            "Humpty Dumpty sat on a wall",
            "Humpty Dumpty had a great fall",
            "All the king's horses and all the king's men",
            "Couldn't put Humpty together again"
        };

        Random random = new Random();

        for(int i=0; i<messages.length; i++) {
            message.write(messages[i]);
            try {
                Thread.sleep(random.nextInt(2000));
            } catch (InterruptedException e) {
                // TODO: handle exception
            }
        }
        message.write("Finished");
    }
}

class Reader implements Runnable {
    private Message message;

    public Reader(Message message) {
        this.message = message;
    }

    public void run() {
        Random random = new Random();

        for(String latestMessage = message.read(); !latestMessage.equals("Finished"); 
                latestMessage = message.read()) {
            System.out.println(latestMessage);

            try {
                Thread.sleep(random.nextInt(2000));
            } catch (InterruptedException e) {
                // TODO: handle exception
            }
        }
    }
}

它在控制台上打印在下面 - 大多数时候并挂起:

Humpty Dumpty sat on a wall

Humpty Dumpty had a great fall

有时它会打印所有四条消息。

我的问题是:Reader 线程如何在 read() 方法中执行代码,而 Writer 线程已经获得了锁并且仍在循环?

我很困惑。请帮我理解!

【问题讨论】:

  • “锁定”是指Message 上的方法是同步的,对吗?请注意,每次编写者离开同步方法时,读者都可以输入一个同步方法。即在方法调用之间。
  • 天哪!我怎么能错过这个?! Note that the reader can enter a synchronized method every time the writer leaves a synchronized method. i.e. in-between method calls.这回答了我的疑惑。我不知何故没有注意到方法执行后锁被释放。非常感谢!

标签: java multithreading synchronized


【解决方案1】:

@Oliver Charlesworth 的评论消除了我的疑虑。我没有注意到每次作者离开同步方法时,读者都可以输入同步方法。程序挂起是因为会有一个线程处于休眠状态的阶段,并且“空”字段的值不会被修改,从而导致其中一个循环无限运行。一旦实现了wait()和notify()方法,问题就迎刃而解了!

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2017-03-08
    相关资源
    最近更新 更多