0
0
采纳的答案
引用
在这个job中的call方法应为有for()循环可以找到在哪中断线程,但是如果只是在连接数据库的话,那就无法知道执行到哪,应该加入中断线程的代码,这应该在外面控制,而不应该在job里面实现中断
线程的中断在JDK1.0版本中提供了stop()方法,但这个方法极度不安全,会不管
当前对象的状态而直接释放所有的monitor,结束线程,会导致对象处于错误的状态。
所以已经不被推荐使用。
试想,有个任务,A向B转账10000¥,需要先从A账户上扣款10000¥,再将B账号加
10000¥,如果A账号扣款完,这是从外面强行杀死线程,会导致什么后果?
中止一个线程最好的方式就是使用中断,在外面通知线程中断,线程将中断状态设置
为true,而具体是否要中断,中断时需要如何处理以保证数据状态是正确的,这些
应交给任务自己处理。
在什么地方控制中断,应该任务中控制,由你的业务逻辑决定,就算是
操作数据库也一样可以设置中断点,或者说更应该判断中断点,来决定是否回滚
事务。
2011年9月01日 18:25
0
0
String N= "";
String M= "";
String id= "";
String pwd = "";
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
this.M = req.getParameter("M").trim();
this.N= req.getParameter("N").trim();
this.id = req.getParameter("id").trim();
this.pwd = req.getParameter("pwd").trim();
/................../
}
当多个系统同时调用该servlet的时候,出现了servlet的非线程安全的问题。比如有两个系统同时调用该servlet,代码中的N、M、id、pwd的值会出现,一个线程的数据被另一个线程的数据“覆盖”的问题。
我的问题是,第一:是否跟这几个变量是全部变量有关,如果设置为局部变量会出现这个问题吗?第二:使用多个servlet能解决这个问题,但是是最好的办法吗?
2011年9月15日 11:34
0
0
楼主cancle地方不对,中断异常后返回也有问题,仔细看下面:public class Test {
private static ExecutorService executor = Executors.newCachedThreadPool();// 定义一个线程池
/**
* @param args
*/
public static void main(String[] args) {
Boolean result = false;
Future future = executor.submit(new MyJob());// 将任务提交到线程池中
try {
result = future.get(20, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
// future.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");// 抛出超时异[size=xx-small][/size]常时打印
//executor.shutdown();// 出现异常即可终止任务。
[color=red]future.cancel(true);[/color]
}
//executor.shutdown();
System.out.println(result);
}
}
class MyJob implements Callable {
@SuppressWarnings("static-access")
@Override
public Boolean call() {
// do job here
//long startTime = System.currentTimeMillis();
//for (int i = 0; System.currentTimeMillis() - startTime < 2000; i++) {
//System.out.println(i);
//}
try {
Thread.currentThread().sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
[color=red]return false; [/color]
}
// 模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
2011年9月08日 19:30
0
0
你对自己要做什么可能很清楚,但你对线程池能做什么确实很模糊,自己把自己绕晕了!!!
回滚事务,如果超时事务回滚到操作以前的场景!
2011年9月07日 17:31
0
0
改了一下你原先的代码import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.Callable;
public class My {
// 业务job
// 实现Callable接口
static class MyJob implements Callable {
public Boolean call() {
// do job here
long startTime = System.currentTimeMillis();
for (int i = 0; System.currentTimeMillis() - startTime < 2000; i++) {
//测试当前线程是否已经中断,配合future.cancel(true)
if (Thread.interrupted())
return false;
}// 模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
private static ExecutorService executor = Executors.newCachedThreadPool();// 定义一个线程池
/**
* @param args
*/
public static void main(String[] args) {
Boolean result = false;
Future future = executor.submit(new MyJob());// 将任务提交到线程池中
try {
result = future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {// 超时异常
System.out.println("Time is out");
future.cancel(true);// 中断执行此任务的线程
}
}
}
测试通过,不会打印"continue..."
2011年9月05日 17:43
0
0
package dl.java.iteye;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.Callable;
public class My {
private static ExecutorService executor = Executors.newCachedThreadPool();// 定义一个线程池
/**
* @param args
*/
public static void main(String[] args) {
Boolean result = false;
MyJob job = new MyJob();
Future future = executor.submit(job);// 将任务提交到线程池中
try {
result = future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");// 抛出超时异[size=xx-small][/size]常时打印
job.thread.stop();
}
}
//业务job
//实现Callable接口
static class MyJob implements Callable {
public Thread thread = null;
@Override
public Boolean call() throws Exception {
//do job here
long startTime = System.currentTimeMillis(); //获取当前运行线程
thread = Thread.currentThread();
for(int i=0;System.currentTimeMillis()-startTime<2000;i++){}//模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
}
这是一个案例,你根据实际情况,修改吧。你可以复制,运行一下。打印结果:
Time is out
2011年9月05日 15:19
0
0
引用
xiaoyang0601 写道
一个这种的办法是获取MyJob当前的线程;在MyJob对象中声明一个变量thread
Java代码
import java.util.concurrent.Callable;
//实现Callable接口
public class MyJob implements Callable {
public Thread thread = null; //定义一个当前任务线程
@Override
public Boolean call() throws Exception {
//do job here
long startTime = System.currentTimeMillis();
thread = Thread.currentThread();//获取当前线程,,外界可以访问
for(int i=0;System.currentTimeMillis()-startTime<2000;i++){}//模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
import java.util.concurrent.Callable;
//实现Callable接口
public class MyJob implements Callable {
public Thread thread = null;
@Override
public Boolean call() throws Exception {
//do job here
long startTime = System.currentTimeMillis();
thread = Thread.currentThread();//获取当前线程for(int i=0;System.currentTimeMillis()-startTime<2000;i++){}//模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
在My对象中当超时,就对该工作任务的线程进行终止。
Java代码
Boolean result = false;
MyJob job = new MyJob();//将提交的任务
Future future = executor.submit(job);// 将任务提交到线程池中
try {
result = future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
// future.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");// 抛出超时异[/size]常时打印
job.thread.stop();//访问MyJob线程。
}
Boolean result = false;
MyJob job = new MyJob();Future future = executor.submit(job);// 将任务提交到线程池中
try {
result = future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
//future.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");// 抛出超时异[size=xx-small]常时打印
job.thread.stop();}
我也想用stop(),但是job.thread取不到该线程啊
能访问到啊。你仔细看看代码。在MyJob中声明一个任务线程,这个任务线程就是当前任务的,在My对象中,声明一个MyJob job = new MyJob();
Future future = executor.submit(job);//
在超时异常代码中
job.thread.stop();是可以访问的。你或许访问修饰符有误。
还有你提的这个问题,中超时不再处理以后的任务,但这个超时的后的任务放在任务中,欠妥,可以提取出来,进行重构,先进性必要的超时处理,如果没有超时在My对象中进行处理业务,如果超时就不再处理。
2011年9月02日 17:10
0
0
一般涉及到网络连接的地方,都会提供超时接口,getConnection也不例外,
不需要自己来控制超时。/**
* Sets the maximum time in seconds that a driver will wait
* while attempting to connect to a database.
*
* @param seconds the login time limit in seconds; zero means there is no limit
* @see #getLoginTimeout
*/
public static void setLoginTimeout(int seconds) {
loginTimeout = seconds;
}
2011年9月02日 16:12
0
0
引用
难道就无解了吗?
暂时没想出来,晚上回去我有开发环境了,我再试试看
2011年9月02日 15:34
0
0
引用
例子很好,不过要在任务中控制,不知道该如何在任务中设置中断点
比如说简单的获取数据库connection,我要在规定时间内判断,若没连接成功就中断线程
因为你获得不到这个JOB所在的线程,所以你没有办法来中断它的。
2011年9月02日 15:26
0
0
引用
我也想用stop()
stop() 已经是不推荐使用了,就算你获得了JOB所在的线程,请也别使用这个方法
2011年9月02日 14:57
0
0
一个这种的办法是获取MyJob当前的线程;在MyJob对象中声明一个变量threadimport java.util.concurrent.Callable;
//实现Callable接口
public class MyJob implements Callable {
[b] public Thread thread = null;[/b]
@Override
public Boolean call() throws Exception {
//do job here
long startTime = System.currentTimeMillis();
[b]thread = Thread.currentThread();[/b]//获取当前线程for(int i=0;System.currentTimeMillis()-startTime<2000;i++){}//模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
在My对象中当超时,就对该工作任务的线程进行终止。
Boolean result = false;
[b]MyJob job = new MyJob();[/b]Future future = executor.submit(job);// 将任务提交到线程池中
try {
result = future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
//future.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");// 抛出超时异[size=xx-small][/size]常时打印
[b]job.thread.stop();[/b]}
2011年9月02日 13:42
0
0
我习惯的做法是在工作线程内部设置一个boolean变量,如果外界想让线程结束就设置一下这个变量。在线程内部会判断这个变量,看是否要退出。
2011年9月01日 21:05
0
0
引用
public class MyJob implements Callable {
@Override
public Boolean call() {
//do job here
long startTime = System.currentTimeMillis();
for(int i=0;System.currentTimeMillis()-startTime<2000;i++){}//模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
你这个测试任务写的有问题,根本没有控制中断,for循环会一直执行到结束。
要在循环中加入线程中断的判断。
Thread.currentThread().interrupted()
引用
public class MyJob implements Callable {
@Override
public Boolean call() {
//do job here
long startTime = System.currentTimeMillis();
for(int i=0;System.currentTimeMillis()-startTime<2000;i++){
if(Thread.currentThread().interrupted()){
return false;
}
}//模拟业务执行超过2000毫秒,即已经超时
System.out.println("continue...");
return true;
}
}
在外面执行future.cancel(true)这时就能结束任务了。
2011年9月01日 17:55
0
0
主要是要实现自己的终止策略
比如在for循环中可以加入这样的判断for(;;){
if(Thread.currentThread().isInterrupted())
return false; //这就是来响应future.cancel啊,你不响应他,咋停啊
}
Java 并发编程实践这本书,看了基本上可以解决大部分问题了
2011年9月01日 17:21
0
0
引用
使用thread能实现吗?还要有返回值的
使用 Thread.sleep() 的话,你可以这么写:
try{
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
System.out.println("continue...");
return true;
2011年9月01日 17:18
0
0
你能把你的for循环里面模仿超时的语句贴出来吗?我用的是Thread.sleep();
2011年9月01日 17:05
0
0
引用
是不是使用线程池提交,线程池将任务分配给多个线程处理了,cancel()后仍然将任务分配给其他的线程执行?这个需要看源码啊。但我认为,应该是针对每一个被submit上去的任务开一个线程来执行
2011年9月01日 17:02
0
0
引用
res为true
呃,那这就奇怪了啊。明明任务已经被取消了,怎么还会打印出下面那句话呢。郁闷啊。。。
2011年9月01日 16:59
0
0
我验证过了在"time is out"的打印后面加future.cancel(true);是可行的,不知道你怎么验证的?
} catch (TimeoutException e) {
System.out.println("Time is out");//抛出超时异[size=xx-small][/size]常时打印
future.cancel(true);
}
2011年9月01日 16:40
0
0
public class My {
private static ExecutorService executor = Executors.newCachedThreadPool();// 定义一个线程池
public static void main(String[] args) {
Future future = executor.submit(new MyJob());// 将任务提交到线程池中
executor.shutdown(); //关闭线程池 不允许再提交任务,并不是关闭线程池中的线程
try {
future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
future.cancel(true);//关闭超时的这个任务
//executor.shutdownNow(); //因为这个任务超时,终止了所有的线程.
System.out.println("Time is out");// 抛出超时异[size=xx-small][/size]常时打印
}
}
/**
*
* 任务。其实完全可以或应该在任务重控制自己何时超时,
* 当然我顺着你的思路来了
*/
public static class MyJob implements Callable {
public Boolean call() throws Exception {
long startTime = System.currentTimeMillis();
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
return false; //这里要响应future的中断啊,
//返回false吧,或者超时了抛个异常也行,这就是所谓的中断策略
//Java5以后的线程终止方法被废了,很多时候终止策略应该自己来实现
}
System.out.println("continue...");
return true;
}
}
}
2011年9月01日 16:28
0
0
catch (TimeoutException e) {
System.out.println("Time is out");//抛出超时异常时打印
boolean res = future.cancel(true);
System.out.println("res:" + res);
}
你这么改一下,看看 res 的值是true 还是 false;
2011年9月01日 15:59
0
0
public class My {
private static ExecutorService executor = Executors.newCachedThreadPool();// 定义一个线程池
/**
* @param args
*/
public static void main(String[] args) {
Boolean result = false;
Future future = executor.submit(new MyJob());// 将任务提交到线程池中
try {
result = future.get(200, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成
//future.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");// 抛出超时异[size=xx-small][/size]常时打印
executor.shutdown();//出现异常即可终止任务。
}
executor.shutdown();
System.out.println(result);
}
}
需要调用 executor.shutdown();
终止当前线程任务。
2011年9月01日 13:51
0
0
在for循环后面抛个异常这样挺好哈
if (System.currentTimeMillis() - startTime >=2000)
throw new TimeoutException();
或者在你的job里实现取消策略,在需要时自己取消。
Future future = executor.submit(new MyJob());// 将任务提交到线程池中
executor.shutdown();//没人提交了该shutdown()了吧
2011年9月01日 13:07
0
0
引用
catch (TimeoutException e) {
System.out.println("Time is out");//抛出超时异[size=xx-small][/size]常时打印
}
在你的System.out.print()语句下,添加一行代码:
future.cancel(true);
看看行不行
2011年9月01日 12:55
0
0
在外面控制时间,200毫秒后,执行
future.cancel(true);
2011年9月01日 12:09
0
0
这好像没什么好办法
future.get(200, TimeUnit.MILLISECONDS)这个只是等结果的时间
2011年9月01日 11:54
315
0
0
1