Structure 如何正确地通知其他线程有关事件的信息?

用户6713148

我正在尝试编写一个线程安全结构来保留键值对并在一定时间延迟后自动删除它们。问题是,容器应该通知其他线程删除。

我也尝试notifyAll()在同步块中使用,但问题仍然存在。

import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;


class Container <K extends Comparable<K>, V> {
    private ConcurrentHashMap <K, V> a;
    private final int delay = 2;
    private final Lock lock = new ReentrantLock();
    private final Condition removed = lock.newCondition();

    public Container() {
        a = new ConcurrentHashMap<>();
    }
    public synchronized void put(K k, V o) {
            lock.lock();
            a.put(k, o);
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(delay);


                    a.remove(k, o);
                    removed.signalAll();
                    lock.unlock();
                } catch (InterruptedException e){
                    e.printStackTrace();
                }

            }).start();

    }

    public  V get(int k)  {

        return a.get(k);
    }

    @Override
    public String toString() {
        return Stream.of(a)
        .filter(Objects::nonNull)
                .map(Object::toString)
                .collect(Collectors.joining(", ", "{", "}"));

    }
}

public class Main {

    public static void main(String [] args) throws InterruptedException {
        Container<Integer, Integer> c = new Container<>();
        c.put(0, 10);
        System.out.println(c);
        c.put(1, 11);
        c.put(2, 12);

        TimeUnit.SECONDS.sleep(3);
        System.out.println(c);

    }
}

程序完成代码0并打印预期值:第一个元素和空结构。但无论哪种方式,我都得到了IllegalMonitorStateException.
任何想法,谢谢。

马丁

我们有几件事要看这里:

  1. lock
  2. removed 这是使用创建的条件 lock

您的主线程lockput方法中获得了锁定但是它永远不会释放锁;相反,它会创建一个新的Thread调用removed.signalAll(). 然而,这个新线程不持有lock执行此操作所需的锁

我认为您需要做的是确保每个锁定的线程lock也解锁它,并且每个调用的线程signalAll也有一个锁。

  public synchronized void put(K k, V o) {

    a.put(k, o);

    new Thread(() -> {
      try {
        TimeUnit.SECONDS.sleep(delay);

        lock.lock(); // get control over lock here
        a.remove(k, o);
        removed.signalAll();
        lock.unlock();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }

    }).start();

  }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

REST:正确返回并提供有关数据的其他信息

在Dspace中存储有关用户的其他信息

如何查找设备类型和有关设备的其他信息

如何查看有关Azure Blob容器租赁的其他详细信息?

Internet Explorer会如何通知其他浏览器有关代理设置的更改?

cpu如何通知内核有关硬件异常的信息?

如何使Redis通知我的服务有关事件

如何报告有关其他问题的错误?

需要Reactjs帮助有关如何正确地将此功能从父按钮组件传递给子按钮组件

如何查找有关 Azure EventHub 的指标“内部服务器错误”和“其他错误”的详细信息

您如何获得有关其他正在运行或重点关注的应用程序的信息?

我可以找到有关正在运行的线程上的事件轮询的哪些信息?

Java-阅读有关其他程序的信息吗?

在外观中包装ElasticSearch SDK,以包含有关某些调用的其他信息

检索有关树枝中奏鸣曲图像的其他信息

从熊猫搜索中获取有关同一行中其他列的信息

在Android上更新有关通知意图的其他数据?

如何显示有关错误的信息?

如何找到有关服务的信息?

如何找到有关“ rootfs”的信息

如何正确地将configure --prefix = XX已安装的程序移动到其他目录?

如何正确地将State传递给React中的其他函数?

如何使用继承或其他方法正确地编写我的POJO?

如何从效果/动作正确地链接调度其他动作

如何通知SonarQube有关软件包重命名的信息?

如何在非交互模式下通知man有关列数的信息?

ListView:如何通过声音和振动通知用户有关新获取的数据的信息?

如何创建Azure警报以通知有关任何资源删除的信息

如何通知Ubuntu 12.04 apt-get有关较早安装的php版本的信息