簡體   English   中英

在Java中使用BlockingQueue在多線程中查找素數

[英]Finding prime number using BlockingQueue in Java with multi threading

我使用BlockingQueue實現了一個多線程程序,以測試數字是否為質數。

要求是程序將提示用戶輸入數字,然后程序將按升序打印每個從2到用戶輸入數字的素數。

我有3類:NumberEnumerationTask用於初始化的BlockingQueue包含了所有的數字是檢查,PrimeRunner為檢查號是質不是,PrimeChecker主類。

NumberEnumerationTask.java

package multithread;

import java.util.concurrent.BlockingQueue;

public class NumberEnumerationTask implements Runnable {
    private BlockingQueue<Integer> queue;
    private Integer maximum;
    public static Integer DUMMY = new Integer(0);

    public NumberEnumerationTask(BlockingQueue<Integer> queue, Integer maximum) {
        this.queue = queue;
        this.maximum = maximum;
    }

    @Override
    public void run() {
        try {
           enumerate();
           queue.put(DUMMY);
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
    }

    /**
    * Create a BlockingQueue contain Integer number from 1 to maximum.
    * @throws InterruptedException
    */
    private void enumerate() throws InterruptedException {
        for (int i = 2; i < maximum; i++) {
           queue.put(i);
        }
    }
}

PrimeRunner.java

package multithread;

import java.util.concurrent.BlockingQueue;

public class PrimeRunner implements Runnable {

    private BlockingQueue<Integer> queue;

    public PrimeRunner(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            boolean done = false;
            while (!done) {
                Integer checkNumber = queue.take();
                if (checkNumber == NumberEnumerationTask.DUMMY) {
                    queue.put(checkNumber);
                    done = true;
                } else {
                    checkPrimeNumber(checkNumber);
                }
            }
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void checkPrimeNumber(Integer number) {
        boolean isPrime = true;
        for (int i = 2; i <= number / 2; i++) {
            if (number % i == 0) {
                isPrime = false;
                queue.remove(number);
                break;
            } 
        }
        if (isPrime == true) {
            System.out.print(number + " ");
            queue.remove(number);
        }
    }
}

PrimeChecker.java

public class PrimeChecker {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.print("Enter maximum number to check: ");
        Integer number = sc.nextInt();

        BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(number);

        NumberEnumerationTask initialize = new NumberEnumerationTask(queue, number);
        new Thread(initialize).start();

        for (int i = 0; i <= number; i++) {
            new Thread(new PrimeRunner(queue)).start();
        }

        sc.close();
    }
}

DUMMY變量用於表示完成。

當我運行該程序時,有時它不是按升序打印的,有時是的。

輸入要檢查的最大數字:100

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

輸入要檢查的最大數字:100

2 3 5 7 11 13 17 19 23 29 31 41 43 47 37 59 61 53 67 71 73 79 83 89 97

有人可以告訴我我的代碼有什么問題嗎? 謝謝

PrimeChecker ,以下代碼是原因:

for (int i = 0; i <= number; i++) {
    new Thread(new PrimeRunner(queue)).start();
}

您創建了多個PrimeRunner實例以及每個實例的一個線程,因此可能會發生以下情況:

  1. 線程1中的PrimeRunner需要5。
  2. 線程2中的PrimeRunner需要7。
  3. 線程2中的PrimeRunner打印7。(線程1中的PrimemeRunner仍在檢查...)
  4. 線程1中的PrimeRunner打印5。

如果只運行一個PrimeRunner ,則可以避免這種情況,並且可以按預期運行。 如果您仍然想通過與PrimeRunner靜態字段中的對象進行synchronizedPrimeRunner圍繞以下部分運行多個PrimeRunnerPrimeRunner應該可以解決該問題:

Integer checkNumber = queue.take();
if (checkNumber == NumberEnumerationTask.DUMMY) {
    queue.put(checkNumber);
    done = true;
} else {
    checkPrimeNumber(checkNumber);
}

線程安全是主要問題。 在您的代碼中,隊列在正在處理的線程之間共享,沒有任何同步機制,因此可能會發生數據損壞,從而導致不可預測的結果。 如果多次運行它,可能會得到不同的結果。

多線程可用於素數檢查以加快主要目標,即可以通過將大數N拆分為多個部分來實現素數查找,並且單個線程將在這些部分上工作,而一個線程將結果匯總。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM