Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否必须将类扩展到ConcurrentHashMap,还是可以使用变量ConcurrentHashMap实现线程安全_Java_Multithreading_Concurrency_Java.util.concurrent_Concurrenthashmap - Fatal编程技术网

Java 我是否必须将类扩展到ConcurrentHashMap,还是可以使用变量ConcurrentHashMap实现线程安全

Java 我是否必须将类扩展到ConcurrentHashMap,还是可以使用变量ConcurrentHashMap实现线程安全,java,multithreading,concurrency,java.util.concurrent,concurrenthashmap,Java,Multithreading,Concurrency,Java.util.concurrent,Concurrenthashmap,我正在创建基于套接字的服务器客户端保留服务,但对于将由多个线程访问的类存在问题,它是否需要扩展ConcurrentHashMap,或者创建变量ConcurrentHashMap就足以保证线程安全 我有两个想法,但我不确定第一个是否可行,因此第一个想法是创建只实现Serializable的类,该类具有变量date,然后是变量ConcurrentHashMap,线程要在其上操作,第二个想法是使用扩展并发哈希映射的类,该类只是CHP,但带有附加变量,以确保它与其他类不同 public class Da

我正在创建基于套接字的服务器客户端保留服务,但对于将由多个线程访问的类存在问题,它是否需要扩展ConcurrentHashMap,或者创建变量ConcurrentHashMap就足以保证线程安全

我有两个想法,但我不确定第一个是否可行,因此第一个想法是创建只实现Serializable的类,该类具有变量date,然后是变量ConcurrentHashMap,线程要在其上操作,第二个想法是使用扩展并发哈希映射的类,该类只是CHP,但带有附加变量,以确保它与其他类不同

public class Day implements Serializable {
private LocalDate date;
private ConcurrentHashMap<String, Boolean> schedule;

public Day(LocalDate date){
    this.date = date;
    this.schedule = new ConcurrentHashMap<>();
    IntStream.range(10, 18).forEachOrdered(
            n -> this.schedule.put(LocalTime.of(n, 0).toString(), TRUE));
}

public void changeaval(String key,Boolean status) {
    this.schedule.replace(key,status);
}

public boolean aval(String key){
    return this.schedule.get(key);
}

public LocalDate getDate(){return this.date;}

public ConcurrentHashMap getSchedule(){return this.schedule;}

}
公共课日实现可序列化{
私有本地日期;
私有ConcurrentHashMap调度;
公众日(本地日期){
this.date=日期;
this.schedule=新的ConcurrentHashMap();
IntStream.range(10,18).forEachOrdered(
n->this.schedule.put(LocalTime.of(n,0.toString(),TRUE));
}
public void changeaval(字符串键,布尔状态){
本.附表.替换(键、状态);
}
公共布尔值aval(字符串键){
返回此.schedule.get(键);
}
public LocalDate getDate(){返回this.date;}
public ConcurrentHashMap getSchedule(){返回this.schedule;}
}
我只想有一个类/对象,它可以被多个线程访问,可以与其他类/对象区分开来,并且有ConcurrentHashMap,它映射Int->Boolean
这是我第一次使用Stack,这是我在Java中的第一个项目,所以如果有什么不对劲,我不知道该怎么说

基本上,这两种方法是等效的。从体系结构的角度来看,最好在专用类中创建变量,因为可以更好地控制用户可以访问哪些方法。扩展时,用户可以访问基础ConcurrentHashMap的许多方法并滥用它们。

处理多线程访问的对象时,基本上需要注意两件事:

  • 竞态条件-由于操作系统的线程调度和编译器的指令重新排序优化,指令以程序员不希望的顺序执行,从而导致错误
  • 内存可见性-在多处理器系统中,一个处理器所做的更改并不总是对其他处理器立即可见。由于性能原因,处理器将内容保存在本地寄存器和缓存中,因此其他处理器执行的线程不可见
  • 幸运的是,我们可以使用适当的同步来处理这两种情况

    让我们谈谈这个特别的节目

    Localdate
    本身就是一个不可变的线程安全类。如果我们查看这个类的源代码,我们会看到这个类的所有字段都是
    final
    。这意味着只要
    Localdate
    的构造函数完成初始化对象,对象本身就可以在多个线程中看到。但是,当它被分配给不同对象中的引用变量时,我们需要注意的是,分配(换句话说,引用变量的内容)是否对其他线程可见

    考虑到您案例中的构造函数,我们可以确保字段
    date
    在线程间的可见性,前提是
    date
    最终的
    易失性的
    。由于您没有修改类中的
    日期
    字段,因此可以很好地将其设置为最终字段,从而确保安全初始化。如果以后决定为该字段使用setter方法(取决于您的业务逻辑和设计),则应使该字段
    为volatile
    ,而不是
    final
    volatile
    创建“发生在”关系,这意味着在写入
    volatile
    变量之前在特定线程中执行的任何指令,在其他线程读取相同的volatile变量后,都将立即可见

    ConcurrentHashMap
    也是如此。您应该将字段设置为“明细表”
    final
    。由于
    ConcurrentHashMap
    本身具有所有必要的同步功能,因此当其他线程尝试读取某个键时,您针对该键设置的任何值都将对其可见

    但是,请注意,如果您有一些可变对象作为
    ConcurrentHashMap
    值而不是
    Boolean
    ,那么您必须以与上述相同的方式设计它

    另外,最好知道有一个称为piggy backing的概念,这意味着如果一个线程写入其所有字段,然后写入
    volatile
    变量,那么在写入
    volatile
    变量之前线程写入的所有内容都将对其他线程可见,假设其他线程在第一个线程写入
    volatile
    变量后第一次读取该变量的值。但是当你这样做的时候,你必须非常小心地确保阅读和写作的顺序,而且很容易出错。因此,当您想要从代码中挤出最后一点性能时,这是很少见的。优先考虑安全性、可维护性和可读性


    最后,代码中没有竞争条件。正在进行的唯一写入操作是在
    ConcurrentHashMap
    上,它本身是线程安全的。

    感谢您的精彩而全面的回答