【问题标题】:Printing Keys of HashMap with two threads in java?在java中用两个线程打印HashMap的键?
【发布时间】:2017-09-02 21:23:10
【问题描述】:

在此处输入代码假设我有两个线程 Thread1 和 Thread2 以及以下具有空值的 hashmap。现在我想用正在执行打印语句的各个线程打印 HashMap 的键,而不是再次打印它

输入哈希图:

“你好”空

“客户”为空

“值”为空

“再见”空

输出:

“再见”:由 Thread1 打印“

"你好" :"由 Thread2 打印"

“值”:“线程2打印”

“客户”:“由 Thread1 打印”

到目前为止,我无法使用以下代码进行打印。

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test2 implements Runnable {
    volatile static HashMap<String, String> map;

    static Object mutex = new Object();

    static volatile int i = 1;

    public static void main(String[] args) throws InterruptedException {

        map = new HashMap();

        map.put("Public", null);
        map.put("Sort", null);
        map.put("Message", null);
        map.put("Customer", null);
        map.put("Bank", null);
        // ConcurrentHashMap chm= new ConcurrentHashMap(map);

        Collections.synchronizedMap(map);

        Thread t1 = new Thread(new Test2());
        Thread t2 = new Thread(new Test2());
        t1.start();
        t2.start();

    }

    @Override
    public void run() {
        synchronized (mutex) {

            for (Map.Entry entry : map.entrySet()) {

                if (entry.getValue() == null) {
                    System.out.println(entry.getKey() + "\" : \"Printed by " + Thread.currentThread().getName() + '\"');

                    map.put((String) entry.getKey(), Thread.currentThread().getName());

                    if (Thread.currentThread().getName().contains("0")&&i==1) {
                        try {
                            mutex.notifyAll();

                            mutex.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    if (Thread.currentThread().getName().contains("1")&&i<=1) {
                        try {
                            mutex.notifyAll();
                             i++;
                            mutex.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                }
            }
            mutex.notifyAll();

        }
    }
}

【问题讨论】:

  • 问题出在哪里?
  • 无法找到打印一次密钥的方法。 @卡米尔
  • 将键收集到一个列表中,将其分成两半,将前半部分传递给第一个线程,将后半部分传递给第二个线程,启动两个线程?我不知道你为什么要这样做,但你可以。如果你想练习多线程,你应该找到一个更现实、更有用的用例。

标签: java multithreading concurrency hashmap synchronization


【解决方案1】:

只需将每个键作为任务传递给具有 2 个线程的 ExecutorService:

ExecutorService executorService = Executors.newFixedThreadPool(2);

map.keySet().forEach(key -> executorService
   .execute(() -> System.out.println('\"' + key + "\" : \"Printed by " + Thread.currentThread().getName() + '\"')));

executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);

【讨论】:

  • @RaviGodara 当然:使用newFixedThreadPool 方法,该方法将ThreadFactory 作为第二个参数,并传递一个根据您的喜好命名线程的方法。
  • 那行得通,还有一个问题,为什么 Executor 服务的行为是线程安全的?不像分别创建两个线程。
  • 因为在底层,ExecutorService 为其任务使用了线程安全队列。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 2015-02-14
  • 2013-05-17
  • 1970-01-01
  • 2013-07-25
  • 2016-03-17
相关资源
最近更新 更多