如何正确使用同步链接哈希图

2024-01-02

尝试通过子类化链接哈希映射来制作 lru 映射。

地图通过 collections.synchronized 运行。

映射的所有用法都被同步块包围。如果它们全部被删除,单元测试也会失败。人们可能会认为它们是不必要的,因为地图是通过 collections.synchronized 运行的。

一个线程将连续数字 (0,1,2,3 ...) 放入映射中。删除由删除的最旧条目处理。没有其他人从地图中删除条目。

另一个线程从地图获取数据。

以下单元测试通常会以“oops”失败。这是当非零数字出现在第一个位置时(它应该为零,直到地图变满)。其他奇怪的事情可能会发生,例如条目集中的空值。

任何指示将不胜感激。

thanks

import static org.junit.Assert.*;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
class LruMap<K,V> extends LinkedHashMap<K,V> {
    public LruMap() {
        super(defaultMaxSize+1,.75f,true);
        maxSize=defaultMaxSize;
    }
    public LruMap(int arg0) {
        super(arg0+1,.75f,true);
        maxSize=arg0;
    }
    public LruMap(int arg0,float arg1) {
        super(arg0+1,arg1,true);
        maxSize=arg0;
    }
    public LruMap(int arg0,float arg1,boolean arg2) {
        super(arg0+1,arg1,arg2);
        if(!arg2)
            throw new RuntimeException("you did not construct an lru map!");
        maxSize=arg0;
    }
    public LruMap(Map<K,V> arg0) {
        super(arg0);
        throw new RuntimeException("you did not construct an lru map!");
    }
    public boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return size()>maxSize;
    }
    public final int maxSize;
    public static final int defaultMaxSize=2048;
    static final long serialVersionUID=0;
}
class Server implements Runnable {
    public Server(final int pieces,final int period) {
        this.pieces=pieces;
        this.period=period;
        lruMap=Collections.synchronizedMap(new LruMap<Long,Long>(3*pieces/2));
    }
    @Override public void run() {
        t0=System.currentTimeMillis();
        while(piece<stopAtPiece) {
            final long dt=System.currentTimeMillis()-t0;
            final long target=piece(dt);
            System.out.println("adding "+(target-piece+1)+" items");
            for(;piece<=target;piece++) {
                synchronized(lruMap) {
                    lruMap.put(piece,piece);
                }
            }
            checkMap(piece,true);
            try {
                Thread.sleep(100);
            } catch(InterruptedException e) {
                e.printStackTrace();
                break;
            }
        }
    }
    Map.Entry<Long,Long>[] checkMap(final long n,boolean print) {
        synchronized(lruMap) {
            Map.Entry<Long,Long>[] entries=null;
            if(lruMap.size()>0) {
                final Set<Map.Entry<Long,Long>> entrySet=lruMap.entrySet();
                entries=new Map.Entry[entrySet.size()];
                entrySet.toArray(entries);
                long first=entries[0].getKey();
                long last=entries[entries.length-1].getKey();
                if(print)
                    for(Map.Entry<Long,Long> entry:entries)
                        System.out.print(entry.getKey()+" ");
                System.out.println();
                if(n<pieces&&first!=0) {
                    System.out.println("lru: first!=0! "+first);
                    if(throwWhenfirstIsNotZero) { throw new RuntimeException("oops"); }
                }
                for(int i=0;i<entries.length-1;i++) {
                    long p0=entries[i].getKey();
                    long p1=entries[i+1].getKey();
                    if(p0>p1)
                        System.out.println("out of order! "+p0+" "+p1);
                    else if(p0==p1)
                        System.out.println("dupicate "+p0+" "+p1);
                    else if(p0+1==p1)
                        ; // ok
                    else if(p0+1<p1)
                        System.out.println("skipped "+p0+" "+p1);
                    else System.out.println("some case i mssed!");
                }
            }
            return entries;
        }
    }
    public long piece(final long dt) {
        return dt/period*pieces+dt%period*pieces/period;
    }
    public boolean throwWhenfirstIsNotZero=true;
    protected long piece;
    public long t0;
    protected long stopAtPiece=Long.MAX_VALUE;
    public final int period;
    public final int pieces;
    public final Map<Long,Long> lruMap;
}
public class ServerTestCase {
    @Before public void setUp() throws Exception {}
    @After public void tearDown() throws Exception {}
    @Test public void testRun() {
        server.stopAtPiece=server.pieces;
        server.throwWhenfirstIsNotZero=true;
        Thread thread=new Thread(server);
        thread.setName("server");
        thread.start();
        while(thread.isAlive()) {
            for(long i=0;i<server.piece;i++)
                synchronized(server.lruMap) {
                    server.lruMap.get(i);
                }
        }
    }
    final int period=2*1000;
    final int serverPieces=100;
    Server server=new Server(serverPieces,period);
}

如果您正在访问某个集合中的集合synchronized(lruMap)块,那么你可能不想将它包裹起来Collections.synchronizedMap()- 使用其中之一。这是因为他们可能会使用不同的锁 - 事实上几乎可以肯定,因为这是极不可能的synchronizedMap()正在使用synchronized(this)内部。

我还推荐在此输入链接描述 http://www.amazon.co.uk/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确使用同步链接哈希图 的相关文章

  • Gradle 构建错误:无法从 https://repo1.maven.org/maven2/io/fabric/tools/gradle/maven-metadata.xml 加载 Maven 元数据

    我在 Android studio 中遇到 gradle 构建错误 如下所示 Error A problem occurred configuring project MyApp Could not resolve all dependen
  • Java中有没有一种方法可以通过名称实例化一个类?

    我正在寻找问题 从字符串名称实例化一个类 https stackoverflow com questions 9854900 instantiate an class from its string name它描述了如何在有名称的情况下实例
  • 如何让 BlazeDS 忽略属性?

    我有一个 java 类 它有一个带有 getter 和 setter 的字段 以及第二对 getter 和 setter 它们以另一种方式访问 该字段 public class NullAbleId private static final
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • 为什么 JTables 使 TableModel 在呈现时不可序列化?

    所以最近我正在开发一个工具 供我们配置某些应用程序 它不需要是什么真正令人敬畏的东西 只是一个具有一些 SQL 脚本生成功能并创建几个 XML 文件的基本工具 在此期间 我使用自己的 AbstractTableModel 实现创建了一系列
  • 使用 LinkedList 实现下一个和上一个按钮

    这可能是一个愚蠢的问题 但我很难思考清楚 我编写了一个使用 LinkedList 来移动加载的 MIDI 乐器的方法 我想制作一个下一个和一个上一个按钮 以便每次单击该按钮时都会遍历 LinkedList 如果我硬编码itr next or
  • Pig Udf 显示结果

    我是 Pig 的新手 我用 Java 编写了一个 udf 并且包含了一个 System out println 其中的声明 我必须知道在 Pig 中运行时该语句在哪里打印 假设你的UDF 扩展了 EvalFunc 您可以使用从返回的 Log
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • 内部类的构造函数引用在运行时失败并出现VerifyError

    我正在使用 lambda 为内部类构造函数创建供应商ctx gt new SpectatorSwitcher ctx IntelliJ建议我将其更改为SpectatorSwitcher new反而 SpectatorSwitcher 是我正
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db
  • Java中super关键字的范围和使用

    为什么无法使用 super 关键字访问父类变量 使用以下代码 输出为 feline cougar c c class Feline public String type f public Feline System out print fe

随机推荐