Java-如何为每一行使用线程搜索数组并在找到后停止所有 运行 线程?
Java-How to search an array using a thread for each row and stop all running threads if found?
我正在尝试通过为每一行使用一个线程来搜索数组中数字 0 的第一次出现,然后如果有一个线程发现该事件则中断所有线程。我阅读了多个问题和答案,但找不到简单的方法,我尝试使用变量“找到”而不是 运行 其他线程。但是,它不起作用,我无法找出问题所在。我主要想使用 interrupt() 而不是使用变量。任何帮助将不胜感激。
搜索class
public class Search extends Thread {
int low;
int high;
int[][] array;
static int id=0;
private static boolean found = false;
private boolean done = false;
public Search(int[][] array, int low, int high) {
id++;
this.array = array;
this.high = high;
this.low= low;
}
public void run(){
whileLoop: while(!found && !done){
for(int i = low; i < high; i++){
for(int j = 0; j < array[i].length; j++){
if(array[i][j] == 0){
System.out.println("Found at: "+i+" "+j + " By thread "+id);
found = true;
done = true;
break whileLoop;
}
}
}
done = true;
}
}
}
主要class
public class Main{
public static void main(String[] args){
int[][] array = {{3,0,2,3,0,5},{2,4,0,2,6,5},{4,1,2,4,6,5},{0,2,1,4,0,5},{4,5,6,0,7,1},{9,7,4,1,1,3}}; //6 zeros
SearchArray searchArray = new SearchArray();
searchArray.sArray(array);
}
}
class SearchArray{
public void sArray(int[][] array){
int noThreads = array.length;
Search[] threads = new Search[noThreads];
for(int i = 0; i < threads.length; i++){
threads[i] = new Search(array, i*1 , (i + 1) * 1);
threads[i].start();
}
}
}
输出:
Found at: 0 1 By thread 5
Found at: 3 0 By thread 6
Found at: 1 2 By thread 5
Found at: 4 3 By thread 6
首先,使用 volatile
关键字是必要的,因为您正在处理由不同线程共享和使用的变量。
我建议只将行传递给线程而不是整个数组。那是不需要的。最后,您可以使用标志来检查是否找到了 0。如果找到,则停止线程。
下面的例子可以满足您的需求。
// the volatile keyword is important
public static volatile int[][] array = {{3,0,2,3,0,5},{2,4,0,2,6,5},{4,1,2,4,6,5},{0,2,1,4,0,5},{4,5,6,0,7,1},{9,7,4,1,1,3}}; //6 zeros
public static volatile boolean found = false;
public static void main(String[] args)
{
for (int i = 0; i < array.length; i++) // Iterate through each row
{
int finalI = i;
Thread th = new Thread() // Create a new thread for each row
{
@Override
public void run()
{
for (int j = 0; j < array[finalI].length; j++) // Each thread will iterate through each element
{
if(found) // If the element 0 was found, then break and stop the thread
{
System.out.println("Another thread found 0, so stopping this thread.");
break;
}
if(array[finalI][j] == 0) // If this is the thread that finds 0, then log and set flag to true
{
System.out.println(this.getName() + " found 0 at index " + finalI + "," + j);
found = true;
break;
}
}
}
};
th.start(); // Start each thread...
}
}
你的found
变量不是volatile
,意思是某个线程找到后,这个线程把found
设置为true
,其他线程不能立即感知,他们会继续寻找。
但是即使设置成volatile
也不够,因为可能多个线程同时找到
所以,如果你想严格控制只有一个线程会打印Found at:...
,你需要使用lock
而不是volatile
(lock->check->act) :
public void run(){
for(int j = 0; j < array[low].length; j++){
if (found) {
break;
}
if(array[low][j] == 0){
// lock,check,act
// if found, lock
// array here can be a lock, since all threads share this array
synchronized (array) {
// check
if (found) {
break;
}
found = true;
System.out.println("Found at: "+low+" "+j + " By thread "+id);
break;
}
}
}
}
我正在尝试通过为每一行使用一个线程来搜索数组中数字 0 的第一次出现,然后如果有一个线程发现该事件则中断所有线程。我阅读了多个问题和答案,但找不到简单的方法,我尝试使用变量“找到”而不是 运行 其他线程。但是,它不起作用,我无法找出问题所在。我主要想使用 interrupt() 而不是使用变量。任何帮助将不胜感激。
搜索class
public class Search extends Thread {
int low;
int high;
int[][] array;
static int id=0;
private static boolean found = false;
private boolean done = false;
public Search(int[][] array, int low, int high) {
id++;
this.array = array;
this.high = high;
this.low= low;
}
public void run(){
whileLoop: while(!found && !done){
for(int i = low; i < high; i++){
for(int j = 0; j < array[i].length; j++){
if(array[i][j] == 0){
System.out.println("Found at: "+i+" "+j + " By thread "+id);
found = true;
done = true;
break whileLoop;
}
}
}
done = true;
}
}
}
主要class
public class Main{
public static void main(String[] args){
int[][] array = {{3,0,2,3,0,5},{2,4,0,2,6,5},{4,1,2,4,6,5},{0,2,1,4,0,5},{4,5,6,0,7,1},{9,7,4,1,1,3}}; //6 zeros
SearchArray searchArray = new SearchArray();
searchArray.sArray(array);
}
}
class SearchArray{
public void sArray(int[][] array){
int noThreads = array.length;
Search[] threads = new Search[noThreads];
for(int i = 0; i < threads.length; i++){
threads[i] = new Search(array, i*1 , (i + 1) * 1);
threads[i].start();
}
}
}
输出:
Found at: 0 1 By thread 5
Found at: 3 0 By thread 6
Found at: 1 2 By thread 5
Found at: 4 3 By thread 6
首先,使用 volatile
关键字是必要的,因为您正在处理由不同线程共享和使用的变量。
我建议只将行传递给线程而不是整个数组。那是不需要的。最后,您可以使用标志来检查是否找到了 0。如果找到,则停止线程。
下面的例子可以满足您的需求。
// the volatile keyword is important
public static volatile int[][] array = {{3,0,2,3,0,5},{2,4,0,2,6,5},{4,1,2,4,6,5},{0,2,1,4,0,5},{4,5,6,0,7,1},{9,7,4,1,1,3}}; //6 zeros
public static volatile boolean found = false;
public static void main(String[] args)
{
for (int i = 0; i < array.length; i++) // Iterate through each row
{
int finalI = i;
Thread th = new Thread() // Create a new thread for each row
{
@Override
public void run()
{
for (int j = 0; j < array[finalI].length; j++) // Each thread will iterate through each element
{
if(found) // If the element 0 was found, then break and stop the thread
{
System.out.println("Another thread found 0, so stopping this thread.");
break;
}
if(array[finalI][j] == 0) // If this is the thread that finds 0, then log and set flag to true
{
System.out.println(this.getName() + " found 0 at index " + finalI + "," + j);
found = true;
break;
}
}
}
};
th.start(); // Start each thread...
}
}
你的found
变量不是volatile
,意思是某个线程找到后,这个线程把found
设置为true
,其他线程不能立即感知,他们会继续寻找。
但是即使设置成volatile
也不够,因为可能多个线程同时找到
所以,如果你想严格控制只有一个线程会打印Found at:...
,你需要使用lock
而不是volatile
(lock->check->act) :
public void run(){
for(int j = 0; j < array[low].length; j++){
if (found) {
break;
}
if(array[low][j] == 0){
// lock,check,act
// if found, lock
// array here can be a lock, since all threads share this array
synchronized (array) {
// check
if (found) {
break;
}
found = true;
System.out.println("Found at: "+low+" "+j + " By thread "+id);
break;
}
}
}
}