简体   繁体   English

线程中的死锁问题

[英]Deadlock issue in threads

I have a method which uses a number to find if it is prime or not. 我有一个方法,使用数字来查找它是否是素数。 I have made 10 threads which would seek a number from the counter and print if it is prime. 我已经制作了10个线程,可以从柜台寻找一个数字,如果它是素数则打印。 When i run the below code there seems to be a deadlock in the program printing just 2 and 3. I am new to threads and so i am pretty sure i am doing a silly mistake. 当我运行下面的代码时,程序打印似乎只有2和3的死锁。我是线程的新手,所以我很确定我做了一个愚蠢的错误。 Can anyone help me out? 谁能帮我吗?

public class Main{

public static int counter=0;

public static void main(String[] args) {

    Thread thread[] = new Thread[10]; //10 threads created

    for(int i=0;i<10;i++){
        thread[i]=new Thread(new NewThread());
        thread[i].start();
    }

}

public static int increment(){

    long count=0;

    count=++counter;

    if(count>1000000000){
        return -1;
    }

    return counter;
}

}


public class NewThread implements Runnable{

    Lock lock=new ReentrantLock();

    public boolean isPrime(int number) throws ThresholdReachedException{

        if(number<0){
            throw new ThresholdReachedException("Limit Reached");
        }

        if(number==1){
            return false;
        }

        double limit=Math.pow(number, 0.5);

        for(int i=1;i<(int)limit;i++){
            if(number%i==0){
                return false;
            }
        }
        return true;
    }

    @SuppressWarnings("static-access")
    @Override
    public void run() {

        //System.out.println(Thread.currentThread().getName()+" running");
        int number=0;
        try{
            while(true){
                if(lock.tryLock()){
                //lock.lock();
                number=Main.increment();
                lock.unlock();
                }else{
                    Thread.currentThread().sleep(2000);;
                }

                if(isPrime(number)){
                    System.out.println(Thread.currentThread().getName()+" Prime number : "+number);
                }
            }
        }catch(ThresholdReachedException e){

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

    }

}

Few things to note: 几点注意事项:

  1. You're declaring lock as an instance variable, not a class variable ( static ). 您将lock声明为实例变量,而不是类变量( static )。 As a result, each thread will have its own copy of it, which defeats the purpose. 结果,每个线程都有自己的副本,这违背了目的。

  2. You don't need to do a tryLock and then sleep -- simply calling .lock() will put the thread to sleep until the lock is available. 你不需要做一个tryLock然后sleep - 只需调用.lock()就会让线程进入睡眠状态,直到锁定可用。 Alternatively, you can bypass using a lock entirely by using an AtomicInteger : https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html 或者,您可以使用AtomicInteger完全绕过锁定: https//docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html

  3. (the actual bug) In your prime checker itself, you're starting the for loop at 1 : n % 1 is always equal to 0, since all integers are (by definition) divisible by 1. The only reason 2 and 3 worked presumably is that limit will be equal to 1 and so the for loop wouldn't run (correct behavior). (实际的错误)在你的素数检查器本身,你在1开始for循环: n % 1总是等于0,因为所有整数(根据定义)可以被1整除。唯一的原因2和3可能工作该limit将等于1,因此for循环不会运行(正确的行为)。 You should start i at 2 instead. 你应该从2开始i

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

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