67,513
社区成员
发帖
与我相关
我的任务
分享
class OuterClass {
private List<Object> data;
public void dataHandler(){
int pageNum = 1;
while( pageNum < maxPage ){
data = dao.getData(pageNum)//从数据库分页查询数据
for(int i= 0;i<4;i++){
linkDataHdl = new linkDataHdlThread();
dataHdlFutures.add(FixedThreadPool.getService().submit(linkDataHdl));
}
List<Object> tempData = dao.getData(pageNum+1);
boolean flag = true;
while( flag){
try {
Thread.sleep(500l);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(Future<Integer> future : dataHdlFutures){
if( !future.isDone()){
flag = true;
}else{
flag = false;
}
}
if(logger.isInfoEnabled()) logger.info("还没处理完~~~~~~~,休眠 Zz~~~.....");
}
pageNum ++;
data = tempData;
}
}
//各个线程互斥访问的方法,每次从链表取出一条记录,但是貌似没有达到互斥的目的
public synchronized Object getElement(){
if( data.size() > 0){
return linkList.remove(0);
}else{
return null;
}
}
//处理数据的方法
public void linkProcessorUnit( Object obj ){
doSomething(obj);//处理数据
dao.insert(obj)//处理完成,插入数据库
}
//这个是用来创建线程的一个内部类
protected class linkDataHdlThread implements Callable<Integer>{
public linkDataHdlThread( ){
}
@Override
public Integer call() throws Exception {
if(logger.isInfoEnabled()) logger.info("线程类"+this.hashCode()+"......");
//线程栈上的一个临时变量,这个线程之间不会共享吧??
List<Object> linkContainer = new ArrayList<Object>();
while(data.size() > 0){//在这个地方调用data.size()是否会有问题
linkContainer.add(getElement());
}
while( linkContainer.size() > 0 ){
linkProcessorUnit(linkContainer.remove(0));
}
return null;
}
}
}
//这个是用来创建线程的一个内部类
protected class linkDataHdlThread implements Callable<Integer>{
public linkDataHdlThread( ){
}
@Override
public Integer call() throws Exception {
if(logger.isInfoEnabled()) logger.info("线程类"+this.hashCode()+"......");
//线程栈上的一个临时变量,这个线程之间不会共享吧??
List<Object> linkContainer = new ArrayList<Object>();
while(data.size() > 0){//在这个地方调用data.size()是否会有问题
linkContainer.add(getElement());
}
while( linkContainer.size() > 0 ){
linkProcessorUnit(linkContainer.remove(0));
}
return null;
}
}
应该改为
//这个是用来创建线程的一个内部类
protected class linkDataHdlThread implements Callable<Integer>{
public linkDataHdlThread( ){
}
@Override
public Integer call() throws Exception {
if(logger.isInfoEnabled()) logger.info("线程类"+this.hashCode()+"......");
//线程栈上的一个临时变量,这个线程之间不会共享吧??
List<Object> linkContainer = new ArrayList<Object>();
Object link = getElement();
while( link != null ){//在这个地方调用data.size()是否会有问题
linkContainer.add(link);
link = getElement();
}
//其实下面这段是画蛇添足了,可以直接在上面的循环里面直接处理 link了
while( linkContainer.size() > 0 ){
linkProcessorUnit(linkContainer.remove(0));
}
return null;
}
}
public synchronized Object getElement(){
if( data.size() > 0){
return linkList.remove(0);
}else{
return null;
}
}
这应该改成这样,哈哈,不过其实并不影响代码的理解:
public synchronized Object getElement(){
if( data.size() > 0){
return data.remove(0);
}else{
return null;
}
}
boolean flag = true;
while( flag){
try {
Thread.sleep(500l);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(Future<Integer> future : dataHdlFutures){
if( !future.isDone()){
flag = true;
break;
}else{
flag = false;
}
}
我在原帖中的代码是没有break的所以导致某个线程还没处理完数据,我的主线程就更新data了,从而发生数据丢失的问题
看一段代码dataHdlFutures.add(FixedThreadPool.getService().submit(linkDataHdl));
这里面dataHdlFutures是一个List<Future<Integer>>, 而FixedThreadPool.getService()是我封装的一个类用来创建一个固定大小的线程池,Future有个方法isDone()是用来判断线程是否终止的。之所以采用这种方案主要有两个原因:
一、用线程池创建线程的消耗要比直接创建线程要小一点
二、可以用Future来很好的判断线程的生命周期,(而不用强制终止线程之类)
最后谢谢两位的支持
写一个A类实现Runnable接口,data作为A的成员变量,四个线程在new的时候都用A作为参数去构造,这样子四个线程就共享data了