简体   繁体   English

Java中的多线程无法按预期工作

[英]multithreading in java is not working as expected

I'm trying to use multithreading in java to check for prime numbers in a certain range. 我试图在Java中使用多线程检查在一定范围内的质数。 Depending on many cores my processor has, I need to create threads to do the work. 根据处理器具有的许多内核,我需要创建线程来完成工作。 I've 4 cores so I've created four threads. 我有4个核心,所以我创建了四个线程。 The problem here is that the threads are not alternating while doing their work. 这里的问题是线程在工作时不会交替。 What happens is first thread starts and does the work, then the second one starts after the first is done, etc. If I use the sleep method, then I can see the threads alternating but that doesn't seem like multithreading to me. 发生的事情是第一个线程启动并开始工作,然后第二个线程在第一个线程完成后启动,依此类推。如果我使用sleep方法,那么我可以看到线程交替出现,但对我来说这似乎不是多线程。 Is there an explanation to that in Java? Java中对此有解释吗? are they actually working simultaneously under the hood but I can't see it? 他们实际上在后台同时工作,但我看不到吗? Thanks in advance, and here's my code: 预先感谢,这是我的代码:

package multithreading;

 import java.util.*;

 public class MultithreadingV2{

static ArrayList<Integer> primes = new ArrayList<>();
static int counter = 0;
    public static synchronized void primeChecker(int rangeStart, int rangeEnd) throws InterruptedException{

        for(int x = rangeStart; x < rangeEnd; x++){

            int temp;
            boolean isPrime=true;

            int numm = x;
            Thread.sleep(50);
            for(int i=2;i<=numm/2;i++)
            {
               temp=numm%i;
               if(temp==0)
               {
                   isPrime=false;                      
                   break;

               }
            }

            if(isPrime){
               System.out.println("thread ID: " + Thread.currentThread().getId());
               System.out.println(numm + " is a Prime Number");
               primes.add(numm);
            }
        }

    }

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

    long startTime = System.currentTimeMillis();

    ArrayList<Integer> primes = new ArrayList<>();

    int processors = Runtime.getRuntime().availableProcessors();
    System.out.println("CPU cores: " + processors);

    int rangeStart = 2;
    int rangeEnd = 1000;

    Thread t1 = null;
    for(int x = 1; x <= processors; x++){
        counter = x;
        t1 = new Thread(){
            public void run(){
                if(counter == 1)
                    try {
                        primeChecker(rangeStart, rangeEnd);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                else if(counter == 2)
                    try {
                        primeChecker(rangeEnd + 1, rangeEnd * 2);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                else if(counter == 3)
                    try {
                        primeChecker((rangeEnd * 2) + 1, rangeEnd * 3);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                else if(counter == 4)
                    try {
                        primeChecker((rangeEnd * 3) + 1, rangeEnd * 4);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

            }

        };

        t1.start();

//          t1.join();
    }

    System.out.println("prime size: " + primes.size());

    long endTime   = System.currentTimeMillis();
    long totalTime = endTime - startTime;
    System.out.println(totalTime);
}


}

The problem is that primeChecker is a static synchronized method. 问题是primeCheckerstatic synchronized方法。 This means that when you call it, you acquire a lock that prevents any other thread from calling the method until your call completes. 这意味着,当您调用它时,您将获得一个锁,该锁将阻止其他任何线程调用该方法,直到调用完成。 In other words, the calculation will be effectively single-threaded; 换句话说,计算将有效地是单线程的; ie no parallelism. 即没有并行性。

Basically, you need to figure out a better way to synchronize the access / updates to your shared state. 基本上,您需要找出一种更好的方法来将访问/更新同步到共享状态。 One that doesn't prevent other threads from making any progress. 一个不会阻止其他线程取得任何进展的线程。

Hint: you only need to synchronize the places where the threads are actually sharing state. 提示:您只需要同步线程实际共享状态的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM