由不同类的线程更新的值不反映在java中的另一个类中
我编辑了我的问题,使之非常简单。 首先,在同一个文件中有两个类 HashMapClass:它创建ConccurentHashMap的实例 及 NewThread:更新hashMap的由不同类的线程更新的值不反映在java中的另一个类中,java,multithreading,Java,Multithreading,我编辑了我的问题,使之非常简单。 首先,在同一个文件中有两个类 HashMapClass:它创建ConccurentHashMap的实例 及 NewThread:更新hashMap的 public class HashMapClass { public static volatile ConcurrentHashMap serverMap = new ConcurrentHashMap(); public static void main(String args[]) { NewT
public class HashMapClass {
public static volatile ConcurrentHashMap serverMap = new ConcurrentHashMap();
public static void main(String args[]) {
NewThread nt = new NewThread();
nt.start();
}
}
class NewThread extends Thread {
@Override
public void run() {
HashMapClass.serverMap.put("Ishan", new Integer(3));
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Logger.getLogger(NewThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
现在,它显示hashMap不是空的,但是如果我尝试从其他类New class访问它,它会显示为空
public class NewClass {
public static void main(String s[]) {
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
Set setMap = HashMapClass.serverMap.entrySet();
Iterator i = setMap.iterator();
for (int f = 0; i.hasNext(); ++f) {
Map.Entry me = (Map.Entry) i.next();
System.out.println("key is" + me.getKey() + "value is :" + me.getValue());
}
}
}
此类永远不会使用数据更新。
我希望这现在很容易理解。HashMap不是线程安全的,因此如果需要跨线程共享HashMap,则需要引入某种形式的同步 或者,更简单地说,使用 作为另一方,您可能会从阅读中受益,尤其是上一部分 编辑 在您的评论之后,请看一个简单的示例,我认为它可以解决您的问题—我的机器上的输出是: 哈希映射在main中为空(第一次尝试)?正确
哈希映射在运行中是否为空?假
哈希映射在main中为空(第二次尝试)?假的 第二次编辑 您可以从另一个类应用相同的逻辑-只需确保调用NewThread.start并等待足够的时间(或者直接调用NewThread.run,以便它在同一个线程中运行,而不必等待):
HashMap不是线程安全的,因此如果需要跨线程共享HashMap,则需要引入某种形式的同步 或者,更简单地说,使用 作为另一方,您可能会从阅读中受益,尤其是上一部分 编辑 在您的评论之后,请看一个简单的示例,我认为它可以解决您的问题—我的机器上的输出是: 哈希映射在main中为空(第一次尝试)?正确
哈希映射在运行中是否为空?假
哈希映射在main中为空(第二次尝试)?假的 第二次编辑 您可以从另一个类应用相同的逻辑-只需确保调用NewThread.start并等待足够的时间(或者直接调用NewThread.run,以便它在同一个线程中运行,而不必等待):
HashMap需要在其同步部分进行处理,因为它缺乏线程安全性 ConcurrentHashMap更擅长并发,ConcurrentHashMap在读取时不会锁定映射,在写入时也不会锁定整个映射。它将锁定当前正在绘制的地图部分 但需要注意的是,如果ConcurrentHashMap在迭代过程中发生更改,ConcurrentHashMap不会抛出ConcurrentModificationException 编辑的代码: 问题是HashMapClass和NewClass的执行,当JVM关闭时,在HashMapClass完成执行后,我们如何运行NewClass类并尝试检索存储在ConcurrentHashMap中的值,该值存储在堆上,一旦JVM终止,该值就会丢失。是的,因为ConcurrentHashMap标记为静态,所以该值存储在堆的内存区域中
public class HashMapClass {
public static ConcurrentHashMap<String,Integer> serverMap = new ConcurrentHashMap<String,Integer>();
public static void main(String args[]) {
NewThread nt = new NewThread();
nt.start();
try {
nt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new NewClass().go();
}
}
class NewThread extends Thread {
@Override
public void run() {
HashMapClass.serverMap.put("Ishan", 3);
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
}
}
class NewClass {
public void go() {
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
for(Map.Entry<String,Integer> m : HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+" "+m.getValue());
}
}
}
公共类HashMapClass{
公共静态ConcurrentHashMap服务器映射=新ConcurrentHashMap();
公共静态void main(字符串参数[]){
NewThread nt=新的NewThread();
nt.start();
试一试{
nt.join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
新建NewClass().go();
}
}
类NewThread扩展线程{
@凌驾
公开募捐{
HashMapClass.serverMap.put(“Ishan”,3);
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
}
}
类NewClass{
公开作废go(){
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
对于(Map.Entry m:HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+“”+m.getValue());
}
}
}
HashMap需要在其同步部分进行处理,因为它缺乏线程安全性
ConcurrentHashMap更擅长并发,ConcurrentHashMap在读取时不会锁定映射,在写入时也不会锁定整个映射。它将锁定当前正在绘制的地图部分
但需要注意的是,如果ConcurrentHashMap在迭代过程中发生更改,ConcurrentHashMap不会抛出ConcurrentModificationException
编辑的代码:
问题是HashMapClass和NewClass的执行,当JVM关闭时,在HashMapClass完成执行后,我们如何运行NewClass类并尝试检索存储在ConcurrentHashMap中的值,该值存储在堆上,一旦JVM终止,该值就会丢失。是的,因为ConcurrentHashMap标记为静态,所以该值存储在堆的内存区域中
public class HashMapClass {
public static ConcurrentHashMap<String,Integer> serverMap = new ConcurrentHashMap<String,Integer>();
public static void main(String args[]) {
NewThread nt = new NewThread();
nt.start();
try {
nt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new NewClass().go();
}
}
class NewThread extends Thread {
@Override
public void run() {
HashMapClass.serverMap.put("Ishan", 3);
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
}
}
class NewClass {
public void go() {
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
for(Map.Entry<String,Integer> m : HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+" "+m.getValue());
}
}
}
公共类HashMapClass{
公共静态ConcurrentHashMap服务器映射=新ConcurrentHashMap();
公共静态void main(字符串参数[]){
NewThread nt=新的NewThread();
nt.start();
试一试{
nt.join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
新建NewClass().go();
}
}
类NewThread扩展线程{
@凌驾
公开募捐{
HashMapClass.serverMap.put(“Ishan”,3);
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
}
}
类NewClass{
公开作废go(){
System.out.println(“哈希映射是否为空”+HashMapClass.serverMap.isEmpty());
对于(Map.Entry m:HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+“”+m.getValue());
}
}
}
指出HashMap不是线程安全的。阅读建议。不要在线程之间共享它。一个快速的解决方法是使用一个。你不能通过反复试验,在你的代码周围撒上“volatile”和“synchronized”,就像在牛排上撒盐一样,让同步正常工作。你必须设计正确。没有别的办法。
public class HashMapClass {
public static ConcurrentHashMap<String,Integer> serverMap = new ConcurrentHashMap<String,Integer>();
public static void main(String args[]) {
NewThread nt = new NewThread();
nt.start();
try {
nt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new NewClass().go();
}
}
class NewThread extends Thread {
@Override
public void run() {
HashMapClass.serverMap.put("Ishan", 3);
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
}
}
class NewClass {
public void go() {
System.out.println("Hash map is empty or not " + HashMapClass.serverMap.isEmpty());
for(Map.Entry<String,Integer> m : HashMapClass.serverMap.entrySet()){
System.out.println(m.getKey()+" "+m.getValue());
}
}
}