我想要执行以下操作:2个线程执行相同的Runnable
对象。他们将生成一个随机数。将数字写入日志。如果数字可以被7分割,则停止两个线程并且发送广播,并且广播接收器使用新标签将最终号码放在日志上。我尝试了interrupt()
和volatile,但由于某种原因,两个线程中的一个会在停止之前运行一个额外的循环。
public boolean onKeyDown(int keyCode, KeyEvent event) {
progDailog = ProgressDialog.show(this, "Progress dialog",
"Working....", true);
Thread one = new Thread(background, "first");
one.start();
Thread two = new Thread(background, "second");
two.start();
return true;
}//
Runnable background = new Runnable() {
public void run() {
while (num1 % 7 != 0 && num % 7 != 0) {
try {
// just doing some long operation
Thread.sleep(1000);
Random rand = new Random();
num = rand.nextInt(9000) + 1000;
name = Thread.currentThread().getName();
tag = "before";
Log.e(tag, name + ":" + num);
if (num % 7 == 0) {
num1 = num;
}
} catch (InterruptedException e) {
} finally {
handler.sendEmptyMessage(0);
progDailog.dismiss();
}
} ;
Intent myObserverSender = new Intent(
"action.GO");
msg = name + ":" + num;
myObserverSender.putExtra("serviceData", msg);
sendBroadcast(myObserverSender);
}
};
public class MyMainLocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context localContext, Intent callerIntent) {
String serviceData = callerIntent.getStringExtra("serviceData");
tag = "after";
Log.e (tag, serviceData);
}
}
这是最终结果
before: first:7877
before: second:9165
before: first:6760
before: second:5663
After: second:5663 <<<< should stop here
before: first:8025 >>>> this's the extra loop
After: first:5663 >>> wrong
顺便问一下,我做的广播是否正确?
答案 0 :(得分:0)
我创建了一个停止线程的简化版本。这是它的工作原理:
interrupt()
方法上的线程停止逻辑。所以,这是完整的代码:
package com.example;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
public class Main {
public static void main(String[] args) {
final List<Thread> threads = new CopyOnWriteArrayList<>();
final AtomicBoolean stopping = new AtomicBoolean(false);
Runnable stopCommand = () -> {
if (!stopping.getAndSet(true)) {
for (Thread thread : threads) {
thread.interrupt();
}
}
};
Background background = new Background(stopCommand);
Thread t1 = new Thread(background);
Thread t2 = new Thread(background);
threads.add(t1);
threads.add(t2);
t1.start();
t2.start();
}
private static class Background implements Runnable {
private Runnable stopCommand;
public Background(Runnable stopCommand) {
this.stopCommand = stopCommand;
}
@Override
public void run() {
Random rand = new Random();
String name = Thread.currentThread().getName();
while (!Thread.currentThread().isInterrupted()) {
int num = rand.nextInt(9000) + 1000;
System.out.println(name + ", num: " + num);
if ((num % 7) == 0) {
stopCommand.run();
}
}
System.out.println(name + " interrupted. Stopping.");
}
}
}
您也可以使用执行程序来代替自己使用列表:
package com.example;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
final ExecutorService ex = Executors.newFixedThreadPool(2);
Runnable stopCommand = () -> {
System.out.println("stopping");
ex.shutdownNow();
};
Background background = new Background(stopCommand);
ex.submit(background);
ex.submit(background);
}
private static class Background implements Runnable {
private Runnable stopCommand;
public Background(Runnable stopCommand) {
this.stopCommand = stopCommand;
}
@Override
public void run() {
Random rand = new Random();
String name = Thread.currentThread().getName();
while (!Thread.currentThread().isInterrupted()) {
int num = rand.nextInt(9000) + 1000;
System.out.println(name + ", num: " + num);
if ((num % 7) == 0) {
stopCommand.run();
}
}
System.out.println(name + " interrupted. Stopping.");
}
}
}