[英]Java Thread Synchronized
This program runs 4 threads and searches for prime numbers from 1 to 100. Sometimes 2 threads are simultaneously attacking and numbers are repeated.该程序运行 4 个线程并搜索从 1 到 100 的质数。有时 2 个线程同时攻击并且数字重复。 I tried to synchronize the thread but I do not know how to do it well.我试图同步线程,但我不知道如何做好。 Can I you can help?我可以帮你吗? Sorry for my bad English对不起,我的英语不好
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
}
}
It would be easier to divide up your search space among the Thread
s when you initialize them so you have no overlap.初始化它们时,在Thread
之间划分搜索空间会更容易,因此您没有重叠。 No clunky synchronization needed.不需要笨重的同步。 Something like this.像这样的东西。
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
}
}
... then in main
... ...然后在main
...
public static void main(String[] args) {
new Thread(new PrimeFinder(0, 25)).start();
new Thread(new PrimeFinder(26, 50)).start();
//and so on
}
As a side note, synchronized
-ing the run
method of your Thread
s is useless.作为旁注, synchronized
Thread
的run
方法是无用的。 Each Thread
gets its own run
method, so nothing else ever competes for that particular lock.每个Thread
都有自己的run
方法,所以没有其他东西会争用那个特定的锁。
In response to your comment:回应你的评论:
If you're forced to do it this way and don't want duplicate numbers added to your list, you can synchronize a wrapper method to add the primes:如果您被迫这样做并且不想将重复的数字添加到您的列表中,您可以同步一个包装方法来添加素数:
public static synchronized void addPrime(int prime) {
if(!primos.contains(prime)) {
primos.add(prime);
}
}
This will ensure that you get no duplicates.这将确保您没有重复。 Then in your Thread
you would have:然后在您的Thread
您将拥有:
if(esPrimo(numero)) {
addPrime(numero);
}
instead of synchronizing run()
you could synchronize the static arrayList primos:您可以同步静态 arrayList primos,而不是同步run()
:
List primos = Collections.synchronizedList(new ArrayList<Integer>());
This ensures that no two threads will test the same number这确保没有两个线程会测试相同的数字
I think synchronizing run()
on a Runnable
is never a good idea.我认为在Runnable
上同步run()
从来都不是一个好主意。 I would simply declare numero as volatile
or change its type to AtomicInteger
我会简单地将 numero 声明为volatile
或将其类型更改为AtomicInteger
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.