在ConcurrentHashMap中的不一致值

huangapple 未分类评论85阅读模式
英文:

Inconsistent value in ConcurrentHashMap

问题

在下面的示例中,ConcurrentHashMap "primesproduced" 返回不一致的值。它不应该总是返回 n 个值吗?

import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ByArrayBlockingQueue {

    private static int currentPrime = 0;
    private static BlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<Integer>();

    static Object lock = new Object();

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

        ConcurrentHashMap<Long, Integer> primesproduced = new ConcurrentHashMap<Long, Integer>();

        Scanner reader = new Scanner(System.in);
        System.out.print("Enter number of threads you want to create: ");
        int n = reader.nextInt();
        reader.close();

        ExecutorService executor = Executors.newFixedThreadPool(n);

        Thread producer = new Thread(() -> {
            long threadId = Thread.currentThread().getId();
            int p = 0;
            try {
                // synchronized (lock) {

                p = generateNextPrime();
                linkedBlockingQueue.put(p);
                primesproduced.put(threadId, p);
                System.out.println("Thread " + threadId + " produced prime number " + p);
                // }
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        });

        Thread consumer = new Thread(() -> {
            long threadId = Thread.currentThread().getId();
            int p = 0;
            try {
                p = linkedBlockingQueue.take();

                System.out.println("Thread " + threadId + " consumed the prime number " + p);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        for (int i = 0; i < n; i++) {
            executor.execute(producer);
            executor.execute(consumer);
        }

        executor.shutdown();

        Thread.sleep(100);

        System.out.println("\nTotal primes produced: " + primesproduced);
    }

    private static int generateNextPrime() {      		
        currentPrime++;
        if (currentPrime < 2) {
            currentPrime = 2;

            return currentPrime;

        }
        for (int i = 2; i < currentPrime; i++) {
            if (currentPrime % i == 0) {
                currentPrime++;
                i = 2;
            } else {
                continue;
            }
        }
        return currentPrime;
    }

}

在不同的运行中,它返回不一致的项目数量,我认为它应该返回生成的项目数量。例如,当 n = 10 时,它只返回六个项目,而不是十个项目。尽管生产者线程生成了 10 个不同的素数。例如:

Enter number of threads you want to create: 10
Thread 19 produced prime number 5
Thread 21 produced prime number 7
Thread 17 produced prime number 3
Thread 23 produced prime number 11
Thread 20 consumed the prime number 2
Thread 22 consumed the prime number 3
Thread 15 produced prime number 2
Thread 19 produced prime number 13
Thread 15 consumed the prime number 17
Thread 22 consumed the prime number 13
Thread 21 consumed the prime number 7
Thread 24 consumed the prime number 5
Thread 18 consumed the prime number 11
Thread 22 consumed the prime number 29
Thread 15 produced prime number 29
Thread 19 consumed the prime number 23
Thread 20 produced prime number 23
Thread 23 produced prime number 19
Thread 16 consumed the prime number 19
Thread 17 produced prime number 17

Total primes produced: {17=17, 19=13, 20=23, 21=7, 23=19, 15=29}

感谢帮助。
谢谢。
英文:

In this example below, the ConcurrentHashMap primesproduced returns inconsistent values. Should not it always return the n number of values?

import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ByArrayBlockingQueue {

	private static int currentPrime = 0;
	private static BlockingQueue&lt;Integer&gt; linkedBlockingQueue = new LinkedBlockingQueue&lt;Integer&gt;();

	static Object lock = new Object();

	public static void main(String[] args) throws InterruptedException {
		
		ConcurrentHashMap&lt;Long, Integer&gt; primesproduced = new ConcurrentHashMap&lt;Long, Integer&gt;();

		Scanner reader = new Scanner(System.in);
		System.out.print(&quot;Enter number of threads you want to create: &quot;);
		int n = reader.nextInt();
		reader.close();

		ExecutorService executor = Executors.newFixedThreadPool(n);

		Thread producer = new Thread(() -&gt; {
			long threadId = Thread.currentThread().getId();
			int p = 0;
			try {
				// synchronized (lock) {

				p = generateNextPrime();
				linkedBlockingQueue.put(p);
				primesproduced.put(threadId, p);
				System.out.println(&quot;Thread &quot; + threadId + &quot; produced prime number &quot; + p);
				// }
			} catch (InterruptedException e) {

				e.printStackTrace();
			}
		});

		Thread consumer = new Thread(() -&gt; {
			long threadId = Thread.currentThread().getId();
			int p = 0;
			try {
				p = linkedBlockingQueue.take();

				System.out.println(&quot;Thread &quot; + threadId + &quot; consumed the prime number &quot; + p);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});

		for (int i = 0; i &lt; n; i++) {
			executor.execute(producer);
			executor.execute(consumer);
		}

		executor.shutdown();

		Thread.sleep(100);    
		
		System.out.println(&quot;\nTotal primes produced: &quot; + primesproduced);    
	}

	private static int generateNextPrime() {      		
		currentPrime++;
		if (currentPrime &lt; 2) {
			currentPrime = 2;
			
			return currentPrime;

		}
		for (int i = 2; i &lt; currentPrime; i++) {
			if (currentPrime % i == 0) {
				currentPrime++;
				i = 2;
			} else {
				continue;
			}
		}
		return currentPrime;
	}

}

In different runs it returns inconsistent number of items, where I think it should return the produced number of items instead. For example with n = 10, it returns only six items, instead of 10 items. The producers threads produced 10 distinct primes though. For example:

Enter number of threads you want to create: 10
Thread 19 produced prime number 5
Thread 21 produced prime number 7
Thread 17 produced prime number 3
Thread 23 produced prime number 11
Thread 20 consumed the prime number 2
Thread 22 consumed the prime number 3
Thread 15 produced prime number 2
Thread 19 produced prime number 13
Thread 15 consumed the prime number 17
Thread 22 consumed the prime number 13
Thread 21 consumed the prime number 7
Thread 24 consumed the prime number 5
Thread 18 consumed the prime number 11
Thread 22 consumed the prime number 29
Thread 15 produced prime number 29
Thread 19 consumed the prime number 23
Thread 20 produced prime number 23
Thread 23 produced prime number 19
Thread 16 consumed the prime number 19
Thread 17 produced prime number 17

Total primes produced: {17=17, 19=13, 20=23, 21=7, 23=19, 15=29}

Appreciate help.
Thanks.

huangapple
  • 本文由 发表于 2020年3月15日 22:11:25
  • 转载请务必保留本文链接:https://java.coder-hub.com/60693799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定