java 子线程不能终止

一易 浪潮(北京)电子信息产业有限公司 Hadoop研发工程师  2013-01-31 09:23:53
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletionService;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;


public class ThreadMessageV03 {

public static void main(String args[]) throws InterruptedException, ExecutionException {
ExecutorService exe = Executors.newFixedThreadPool(2);
SyncTest3 st = new SyncTest3();
CyclicBarrier cb = new CyclicBarrier(2);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>();

for (int i=0; i<2; i++) {
Future<Integer> future = exe.submit(st);
futures.add(future);
}

//exe.shutdownNow();

//等待所有线程执行完
try {
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}

for (int i=0; i<futures.size(); i++) {
System.out.println(futures.get(i).get());
}
System.out.println("程序结束!");
}
}




class SyncTest3 implements Callable<Integer> {

private int flag = 1;
public synchronized int getFlag() {
return flag;
}

public synchronized void setFlag(int flag) {
this.flag = flag;
}

private static int sum = 0;

public Integer call() {
if (getFlag() == 1) {
System.out.println(Thread.currentThread().getName() + "-flag:" + getFlag());
for (int i=0; i<20; i++) {
//System.out.println(Thread.currentThread().getName() + "-i=" + i);
synchronized (this) {
if (sum >= 10) {
setFlag(0);
System.out.println(Thread.currentThread().getName() + "-flag:" + getFlag());
break;
}
sum ++;
}
System.out.println(Thread.currentThread().getName() + "-sum=" + sum);
}
}
System.out.println(Thread.currentThread().getState());

return sum;
}
}
...全文
115 3 点赞 打赏 收藏 举报
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
nmyangym 2013-01-31
楼主在代码里构造了一个有2个参与者的CyclicBarrier对象,但用在主线程里,永远也不会有两个主线程,所以程序一直阻塞在那里。子线程已经执行完,主线程还在阻塞。
  • 打赏
  • 举报
回复
nmyangym 2013-01-31
试了下代码,这样可以结束, 1 不需要设置cb.await(),线程池里的线程如果没执行完,futures.get(i).get()会阻塞的。所以不要那段代码。 2 程序结束还是要加上语句:exe.shutdown(); 修改后的代码:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletionService;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

//import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;//用不到。


public class ThreadMessageV03 {
    public static void main(String args[]) throws InterruptedException, ExecutionException {
        ExecutorService exe = Executors.newFixedThreadPool(2);
        SyncTest3 st = new SyncTest3();
        CyclicBarrier cb = new CyclicBarrier(2);
        List<Future<Integer>> futures = new ArrayList<Future<Integer>>();

        for (int i=0; i<2; i++) {
            Future<Integer> future = exe.submit(st);
            futures.add(future);
        }

        //exe.shutdownNow();

        //等待所有线程执行完// 这段不要。
        /*try {
            cb.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }*/

        for (int i=0; i<futures.size(); i++) {
            System.out.println("futures.get("+i+").get()     "+futures.get(i).get());//能看到具体哪个线程。
        }
        System.out.println("程序结束!");
        exe.shutdown();//加上
    }
}


class SyncTest3 implements Callable<Integer> {
    private int flag = 1;
    public synchronized int getFlag() {
        return flag;
    }

    public synchronized void setFlag(int flag) {
        this.flag = flag;
    }

    private static int sum = 0;
    public Integer call() {
        if (getFlag() == 1) {
            System.out.println(Thread.currentThread().getName() + "-flag:" + getFlag());
            for (int i=0; i<20; i++) {
                //System.out.println(Thread.currentThread().getName() + "-i=" + i);
                synchronized (this) {
                    if (sum >= 10) {
                        setFlag(0);
                        System.out.println(Thread.currentThread().getName() + "-flag:" + getFlag());
                        break;
                    }
                    sum ++;
                }
                System.out.println(Thread.currentThread().getName() + "-sum=" + sum);
            }
        }
        System.out.println(Thread.currentThread().getName()+" is  "+Thread.currentThread().getState());//加上线程名。
        return sum;
    }
}
  • 打赏
  • 举报
回复
一易 2013-01-31
请大侠指点,急需答案,非常感谢
  • 打赏
  • 举报
回复
相关推荐
发帖
Java SE
加入

6.2w+

社区成员

Java 2 Standard Edition
申请成为版主
帖子事件
创建了帖子
2013-01-31 09:23
社区公告
暂无公告