日期:2014-05-20  浏览次数:20757 次

帮忙看下这两段代码有什么问题,关于线程同步问题

package com.demo.service.include.impl;

import java.util.concurrent.CountDownLatch;

public class A implements Runnable{
CountDownLatch latch;//同步辅助类
private String flag;

public CountDownLatch getLatch() {
return latch;
}

public void setLatch(CountDownLatch latch) {
this.latch = latch;
}

public String getFlag() {
return flag;
}



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



@Override
public void run() {
try{
setFlag("B");
throw new Exception();
}catch(Exception e){
setFlag("A");
}finally{
latch.countDown();
}
}

}



package com.demo.service.include.impl;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class B {
public static void main(String[] args) throws InterruptedException {
ExecutorService t=Executors.newCachedThreadPool();
CountDownLatch latch=new CountDownLatch(1);
A a=new A();
a.setLatch(latch);
t.execute(a);
latch.await();
System.out.println(a.getFlag());
}
}

以上代码在运行完后,没有立即退出,不知道为什么卡住,最终也打印出A结果

假设在通过spring的方式将a进行配置,返回值却获取不到,这个是为什么?
------解决方案--------------------
引用:
恩,确实是这样的,方便说明一下原因吗?

虚拟机实例停止运行的条件是:只有守护线程时才退出;

显然,即使main线程退出,若线程池还有非守护线程,自然JVM还在运行了;
------解决方案--------------------
线程池,简而言之,就是线程的池,在池中容纳一定数量的线程,有任务要执行时,从池中取出一个线程,执行所需的任务,执行完成后,线程并不是直接结束,而是等待下一个任务的到来,这样可以避免每次有任务需要执行时都要重复创建线程的开销。当然线程池中的线程并不是永不结束,可以设置超时时间,如果一个空闲的线程等待了超过超时时间还没有任务需要执行,那么线程就自动结束,也就达到了从线程池中删除线程的目的。
具体可以看下ThreadPoolExecutor中的:
Runnable getTask() {
        for (;;) {
            try {
                int state = runState;
                if (state > SHUTDOWN)
                    return null;
                Runnable r;
                if (state == SHUTDOWN)  // Help drain queue
                    r = workQueue.poll();
                else if (poolSize > corePoolSize 
------解决方案--------------------
 allowCoreThreadTimeOut)
                    r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
                else
                    r = workQueue.take();
                if (r != null)
                    return r;
                if (workerCanExit()) {
                    if (runState >= SHUTDOWN) // Wake up others
                        interruptIdleWorkers();
                    return null;
                }
                // Else retry
            } catch (InterruptedException ie) {
                // On interruption, re-check runState
            }
        }
    }