Java线程同步

Java线程同步,java,multithreading,synchronization,Java,Multithreading,Synchronization,这个程序运行4个线程,搜索从1到100的素数。有时,两个线程同时攻击,并且数字重复。我试图同步线程,但我不知道如何做好。你能帮忙吗?对不起,我英语不好 import java.util.ArrayList; public class EjemploThread1 extends Thread{ static int numero=1; static ArrayList<Integer> primos = new ArrayList<Integer>()

这个程序运行4个线程,搜索从1到100的素数。有时,两个线程同时攻击,并且数字重复。我试图同步线程,但我不知道如何做好。你能帮忙吗?对不起,我英语不好

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
     }
}
import java.util.ArrayList;
公共类EJMPOTHREAD1扩展了线程{
静态整数=1;
静态ArrayList primos=新ArrayList();
公共同步的无效运行(){
//试一试{
而(数字<100){
数字++;
如果(!primos.contains(numero)&&esPrimo(numero))
{
加上(数字);
}
notifyAll();
//收益率();
试一试{
睡眠(1);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
//主要
公共静态void main(字符串[]args)引发InterruptedException{
Ejempothread1 hilos=null;
int n_hilos=4;
//克利尔洛斯4希洛斯酒店

对于(int i=0;i来说,在初始化
线程时,在
线程中划分搜索空间会更容易,这样就不会有重叠。不需要笨拙的同步。类似这样的情况

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
    }
}
作为旁注,
synchronized
-ing您的
线程的
运行
方法是无用的。每个
线程
都有自己的
运行
方法,因此没有其他方法会争夺特定的锁

针对你的评论:

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

public static synchronized void addPrime(int prime) {
    if(!primos.contains(prime)) {
        primos.add(prime);
    }
}
这将确保没有重复。然后在
线程中,您将有:

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

您可以同步静态arrayList primos,而不是同步
run()

 List primos = Collections.synchronizedList(new ArrayList<Integer>());
List primos=Collections.synchronizedList(新的ArrayList());

这确保了没有两个线程将测试相同的数字

我认为在可运行的
上同步
run()
从来都不是一个好主意。我只需将numero声明为或将其类型更改为

我也像您一样认为,但我必须同时运行所有操作。无论如何,谢谢:)@黑代码仍然在同时运行,只是在数据块上。@TheBlackCode基于此更新了我的答案。:)最后一个方法应该满足您的需要。
 List primos = Collections.synchronizedList(new ArrayList<Integer>());