纯贴拒绝无意义灌水:顶、学习、JF……之类的垃圾回复
(JDK1.5+)在多线程中,我们要得到子线程的结果一般就使用callable接口,用future来获取子线程的返回值。那么在试验中发现如果用了callable接口,那子线程中的操作好像都变成了“串行”?这是怎么回事?如果变成了串行,那我多线程还有什么意义??有没有高手来解答一下?具体举个事例如下:10个人百米赛跑,裁判开枪10个人同时起跑,最后一个人跑完100米,比赛结束。那么在这个事例中,10个人就是10个子线程,每个线程干的事就是跑完100米。主线程要获取最后一个线程跑完100米的时间,然后主线程结束。测试代码:public abstract class FutureProxy{ private final class CallableImpl implements Callable{ public Object call() throws Exception {
return FutureProxy.this.createInstance();
}
}
private static class InvocationHandlerImpl implements InvocationHandler { private Future future;
private volatile Object instance;
InvocationHandlerImpl(Future future){
this.future = future;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
synchronized(this){
if(this.future.isDone()){
this.instance = this.future.get();
}else{
while(!this.future.isDone()){
try{
this.instance = this.future.get();
}catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
return method.invoke(this.instance, args);
}
}
} private static final class ThreadFactoryImpl implements ThreadFactory { public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
} private static ExecutorService service = Executors.newCachedThreadPool(new ThreadFactoryImpl()); protected abstract Object createInstance(); protected abstract Class getInterface();
public final Object getProxyInstance() {
Class interfaceClass = this.getInterface();
if (interfaceClass == null || !interfaceClass.isInterface()) {
throw new IllegalStateException();
} Callable task = new CallableImpl(); Future future = FutureProxy.service.submit(task); return (Object) Proxy.newProxyInstance(interfaceClass.getClassLoader(),
new Class[] { interfaceClass }, new InvocationHandlerImpl(future));
}
}
interface DateTest{ String getDate();
} class DateTestImpl implements DateTest{
private String _date=null;
public DateTestImpl(){
try{
_date+=Calendar.getInstance().getTime();
}catch(Exception e){
}
}
public String getDate() {
//A.method是一个费时操作,比如读取数据库之类的……
A a=new A();
String s="";
if(a.method()){
s="a:"+Calendar.getInstance().getTime();
}else{
s="b:"+Calendar.getInstance().getTime();
}
return "date "+_date+":"+s;
}
} class DateTestFactory extends FutureProxy{ protected Object createInstance() {
return new DateTestImpl();
}
protected Class getInterface() {
return DateTest.class;
}
}public class Test{ public static void main(String[] args) {
DateTestFactory factory = new DateTestFactory();
DateTest[] dts = new DateTest[10];
for(int i=0;i<dts.length;i++){
dts[i]=(DateTest)factory.getProxyInstance();
}
for(int i=0;i<dts.length;i++){
System.out.println(dts[i].getDate());
}
}
}
在示例代码中运行发现,A.method是我想用多线程(循环顺序执行浪费时间为了节省时间使用多线程)执行的一个操作,可打出来的结果发现s值时间是顺序的:Tue Jul 07 10:35:20 CST 2009
Tue Jul 07 10:35:25 CST 2009
Tue Jul 07 10:35:30 CST 2009
高手解答下为什么会这样?那我为了节省时间使用多线程该怎么办?
(JDK1.5+)在多线程中,我们要得到子线程的结果一般就使用callable接口,用future来获取子线程的返回值。那么在试验中发现如果用了callable接口,那子线程中的操作好像都变成了“串行”?这是怎么回事?如果变成了串行,那我多线程还有什么意义??有没有高手来解答一下?具体举个事例如下:10个人百米赛跑,裁判开枪10个人同时起跑,最后一个人跑完100米,比赛结束。那么在这个事例中,10个人就是10个子线程,每个线程干的事就是跑完100米。主线程要获取最后一个线程跑完100米的时间,然后主线程结束。测试代码:public abstract class FutureProxy{ private final class CallableImpl implements Callable{ public Object call() throws Exception {
return FutureProxy.this.createInstance();
}
}
private static class InvocationHandlerImpl implements InvocationHandler { private Future future;
private volatile Object instance;
InvocationHandlerImpl(Future future){
this.future = future;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
synchronized(this){
if(this.future.isDone()){
this.instance = this.future.get();
}else{
while(!this.future.isDone()){
try{
this.instance = this.future.get();
}catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
return method.invoke(this.instance, args);
}
}
} private static final class ThreadFactoryImpl implements ThreadFactory { public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
} private static ExecutorService service = Executors.newCachedThreadPool(new ThreadFactoryImpl()); protected abstract Object createInstance(); protected abstract Class getInterface();
public final Object getProxyInstance() {
Class interfaceClass = this.getInterface();
if (interfaceClass == null || !interfaceClass.isInterface()) {
throw new IllegalStateException();
} Callable task = new CallableImpl(); Future future = FutureProxy.service.submit(task); return (Object) Proxy.newProxyInstance(interfaceClass.getClassLoader(),
new Class[] { interfaceClass }, new InvocationHandlerImpl(future));
}
}
interface DateTest{ String getDate();
} class DateTestImpl implements DateTest{
private String _date=null;
public DateTestImpl(){
try{
_date+=Calendar.getInstance().getTime();
}catch(Exception e){
}
}
public String getDate() {
//A.method是一个费时操作,比如读取数据库之类的……
A a=new A();
String s="";
if(a.method()){
s="a:"+Calendar.getInstance().getTime();
}else{
s="b:"+Calendar.getInstance().getTime();
}
return "date "+_date+":"+s;
}
} class DateTestFactory extends FutureProxy{ protected Object createInstance() {
return new DateTestImpl();
}
protected Class getInterface() {
return DateTest.class;
}
}public class Test{ public static void main(String[] args) {
DateTestFactory factory = new DateTestFactory();
DateTest[] dts = new DateTest[10];
for(int i=0;i<dts.length;i++){
dts[i]=(DateTest)factory.getProxyInstance();
}
for(int i=0;i<dts.length;i++){
System.out.println(dts[i].getDate());
}
}
}
在示例代码中运行发现,A.method是我想用多线程(循环顺序执行浪费时间为了节省时间使用多线程)执行的一个操作,可打出来的结果发现s值时间是顺序的:Tue Jul 07 10:35:20 CST 2009
Tue Jul 07 10:35:25 CST 2009
Tue Jul 07 10:35:30 CST 2009
高手解答下为什么会这样?那我为了节省时间使用多线程该怎么办?
import java.util.concurrent.*;public class CallableExample { public static class WordLengthCallable
implements Callable {
private String word;
public WordLengthCallable(String word) {
this.word = word;
}
public Integer call() {
return Integer.valueOf(word.length());
}
} public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<Integer>> set = new HashSet<Future≶Integer>>();
for (String word: args) {
Callable<Integer> callable = new WordLengthCallable(word);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future<Integer> future : set) {
sum += future.get();
}
System.out.printf("The sum of lengths is %s%n", sum);
System.exit(sum);
}
}