我有一个任务x,它在一个线程中连续执行,只有在布尔值将其状态变为true时才会停止。我已经做了一些阅读,在杀死下面代码中的线程时,我有3种方法。 3种方法中哪一种有效?如果它们都没有效果或正确,请提供适当的方法,并提供一些代码供参考。
以下是代码:
public class MyTest {
private static class transaction {
private String param1,param2,param3, param4, param5;
public transaction (String param1,String param2,String param3,String param4,String param5){
this.param1=param1;
this.param2=param2;
this.param3=param3;
this.param4=param4;
this.param5=param5;
}
public String getParam1(){
return this.param1;
}
public String getParam2(){
return this.param2;
}
public String getParam3(){
return this.param3;
}
public String getParam4(){
return this.param4;
}
public String getParam5(){
return this.param5;
}
}
public static void processBatch(String workerName){
try{
java.util.List <transaction> transactions= new java.util.LinkedList<transaction>();
java.sql.ResultSet dbtrx=Database.db.execQuery((Object)"dbname.procname");
while(dbtrx.next()){// Takes a snapshot of the pending payments in the table and stores it into the list.
Object obj=new transaction (dbtrx.getString("col1"), dbtrx.getString("col2"), dbtrx.getString("col3"), dbtrx.getString("col4"), dbtrx.getString("col5"));
transactions.add((transaction)obj);
obj=null;
}
java.util.Iterator<transaction> iterate= transactions.iterator();
/* Processes the pending batch payments*/
while(iterate.hasNext()){
transaction trx=iterate.next();
/*Calls posting function here*/
System.out.println(workerName+":- Param1 : "+trx.getParam1()+" - Param2 : " +trx.getParam2()+
" - Param3 : "+ trx.getParam3()+" - Param4 : "+ trx.getParam4()+" - Param5 : "+ trx.getParam5());
iterate.remove();
}
/*cleaning object references*/
dbtrx=null;
transactions=null;
iterate=null;
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args) throws InterruptedException{
volatile boolean stop=false;
Object hold= new Object();
new Thread("Batch Worker A"){
@Override
public void run(){
while(true){
if(stop!=true){
processBatch(Thread.currentThread().getName());
}else{
try{
Thread.sleep(0);
Thread.currentThread().interrupt();
}catch(java.lang.InterruptedException e){
Thread.currentThread().interrupt();
break;
}
}
}
}}.start();
new Thread("Batch Worker B"){
@Override
public void run(){
try{
while(stop!=true){
processBatch(Thread.currentThread().getName());
}
Thread.sleep(0);
Thread.currentThread().interrupt();
}catch(java.lang.InterruptedException e){
Thread.currentThread().interrupt();
}
}}.start();
new Thread("Batch Worker C"){
@Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
if(stop!=true){
processBatch(Thread.currentThread().getName());
}else{
Thread.currentThread().interrupt();
}
}
}}.start();
}
}
}
答案 0 :(得分:6)
推荐的方法是使用线程的中断标志来通知线程循环终止。没有理由使用两个标志(stopped
和中断的标志),而且你似乎没有使用被打断的标志。
有关更广泛的讨论和示例,请参阅Java教程主题Interrupts。
答案 1 :(得分:3)
为什么不这么简单:
new Thread("Batch Worker A"){
@Override
public void run() {
while(!stop){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
或者,像这样使用Thread.interrupt()
:
new Thread("Batch Worker A"){
@Override
public void run() {
while(!interrupted()){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
但是你需要保持对所有线程的引用,并将它们全部中断,所以boolean标志可能更简单(确保它变得不稳定)。
答案 2 :(得分:1)
在所有示例中,您并没有真正杀死该线程,您正在停止批处理以处理更多项目。 要理解这些差异,请注意,当线程在processBatch函数中时,您的方法都不会实际停止线程。
有些事情需要注意:
如果您的目标仅仅是停止下一批处理,请使用Joonas中的代码:
new Thread("Batch Worker A"){
@Override
public void run() {
while(!stop){
processBatch(Thread.currentThread().getName());
}
}
}}.start();
如果您的目标是在运行批处理时中断该过程,您也可以这样做:
public static void main(String[] args) {
var t =new Thread("Batch Worker A"){
@Override
public void run() {
processBatch(Thread.currentThread().getName());
}
}.start();
t.interrupt();
}
一般来说,中断是首选方法,并且使用本地范围的变量和匿名类是一个非常糟糕的主意(使用静态变量,或者更好的注入接口与函数来检查线程是否应该继续)。