Java线程同步

标签 java multithreading synchronization

该程序运行4个线程,搜索1到100之间的质数。有时2个线程同时攻击,数字重复。我尝试同步线程,但我不知道如何做好。我可以帮你吗?抱歉我的英语不好

import java.util.ArrayList;

public class EjemploThread1 extends Thread{

    static int numero=1;
    static ArrayList<Integer> primos = new ArrayList<Integer>() ; 

    public synchronized void run() {
        //try {
        while (numero < 100){
            numero++;

            if (!primos.contains(numero) && esPrimo(numero))
            {
                primos.add(numero);
            }

            notifyAll();

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


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

        EjemploThread1 hilos = null;

        int n_hilos=4;

        //Crear los 4 Hilos
        for (int i=0;i<=n_hilos;i++) {
            hilos = new EjemploThread1();
            hilos.start();
        }

        for (int i=0;i<=n_hilos;i++) {
            hilos.join(); 
        }

        //cuando finalizen los hilos(join) continuara y mostrara el vector:
        System.out.println("\nVECTOR NUMEROS PRIMOS: ");
        for(int i=0; i < primos.size(); i++)
        {
            System.out.print(primos.get(i) + " ");  
        }
    }

    //FUNCION SABER SI ES PRIMO
    public static boolean esPrimo(int numero)
     {
        for(int i=2; i<numero; i++)
        {
            if(numero % i == 0) return false; //no es primo
        }         
        return true; //es primo
     }
}

最佳答案

初始化Thread时,在Thread之间划分搜索空间会更容易,这样就不会重叠。不需要笨重的同步。像这样的东西。

public class PrimeFinder implements Runnable {

    private int rangeStart;
    private int rangeEnd;

    public PrimeFinder(int start, int end) {
        rangeStart = start;
        rangeEnd = end;
    }

    public void run() {
        //check for primes where rangeStart <= x <= rangeEnd
    }
}

...然后在main...

public static void main(String[] args) {
    new Thread(new PrimeFinder(0, 25)).start();
    new Thread(new PrimeFinder(26, 50)).start();
    //and so on
}

顺便说一句,synchronized - Threadrun 方法是没有用的。每个Thread都有自己的run方法,因此没有其他东西会竞争该特定的锁。

回复您的评论:

如果您被迫这样做,并且不希望将重复的数字添加到您的列表中,您可以同步包装方法来添加素数:

public static synchronized void addPrime(int prime) {
    if(!primos.contains(prime)) {
        primos.add(prime);
    }
}

这将确保您不会得到重复的内容。然后在您的 Thread 中您将拥有:

if(esPrimo(numero)) {
    addPrime(numero);
}

关于Java线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22866058/

相关文章:

python - 我应该如何处理Python中访问sqlite数据库的多个线程?

javascript - 多设备间同步JS时间

java - 如何在java中识别已检查和未检查的异常?

java - java格式化文本文件

java - 无法解析 DuplicateKeyException 上的符号 'logger'

database - 如何同步两个 Oracle 数据库?

synchronization - 同步数据的最佳实践

java - Jackson 解析 JSON(700 KB 文件)需要 30 秒以上

java - newScheduledThreadPool() 方法的参数 "corePoolSize"是什么意思?

c# - 不能通过并发线程访问破坏数据