多线程+批处理的问题

时间:2021-11-29 21:02:13

其他地方有多线程调用putBeat方法,当list里面有8000条数据的时候就做一次批处理,现在想如果5秒内没有数据进来,则不满8000条也做同样的批处理操作, 这个时间改怎么加呢
public class T {

private int batchSize = 8000;
private Object object;
private ArrayList<String> list = new ArrayList<String>();

public void putBeat(String rtua, String heartBeatTime) {

synchronized (object) {
if (list.size()>batchSize) {
//存满batchSize后做批处理
}
list.add(rtua+heartBeatTime);
/**
 * 如果5秒内没有数据进来,则也做批处理
 */
}// end
}
}

21 个解决方案

#1


没感觉,线程的运行时间本身就不确定,又如何来判断五秒?

#2


线程是一直运行的 有数据进来的时候就插入list 里面

#3


同意1楼

#4


引用 2 楼 languo 的回复:
线程是一直运行的 有数据进来的时候就插入list 里面


如果是这样,可以在程序外边写个小程序,算时间用的,可以int n,每过一秒自动+1,

然后在程序public void putBeat(String rtua, String heartBeatTime)

里面判断是否n==5,等于5了就操作

#5


sleep

#6


还是不懂 刚接触多线程开发

#7


这个在多线程的话,确实不知道怎么加了,不知道你的同步关系

#8


在外部做控制,做一个每个5秒执行的定时器,当执行了putBeat方法时,将记时器重置.若5秒后没有执行方法,则自动执行一次,传入一个null.在你的putBeat方法中判断一下,如果传入的是null的话就不要add到list中

#9


不懂 学习中

#10


定义一个开始时间和结束时间,相减小于5秒就做操作,直接写在方法里面

#11


在后台用一个定时器处理:crontab

#12


引用 8 楼 cosmos1984 的回复:
在外部做控制,做一个每个5秒执行的定时器,当执行了putBeat方法时,将记时器重置.若5秒后没有执行方法,则自动执行一次,传入一个null.在你的putBeat方法中判断一下,如果传入的是null的话就不要add到list中

楼上的方法是可行的,也可以把原来的类也改成一个单独的线程,其他线程add的时候先添加到另外一个列表,然后notify这个线程,由这个单独线程完成add和提交操作,如果是add操作,然后这个单独的线程开始wait,设定为5秒就可以了。

#13


引用 12 楼 fastmask 的回复:
引用 8 楼 cosmos1984 的回复:
在外部做控制,做一个每个5秒执行的定时器,当执行了putBeat方法时,将记时器重置.若5秒后没有执行方法,则自动执行一次,传入一个null.在你的putBeat方法中判断一下,如果传入的是null的话就不要add到list中 
 
楼上的方法是可行的,也可以把原来的类也改成一个单独的线程,其他线程add的时候先添加到另外一个列表,然后notify这个线程,由这个单独线程完成add和提交操作,如果是add操作,然后这个单…


顶!
不太清楚你的业务,简单做一个例子吧,跟上面说的是一个意思. 这里直接把Timer写成了T的一个属性了,根据业务,这个Timer应该是系统唯一的(单例的),你再根据业务调整吧, 不知道是不是你想要的功能.  这里是BlockedTimer的说明:

class T {

    private int batchSize = 8000;    
    private static int maxIdle=5000;
    private Object object;
    private List<String> list = new ArrayList<String>();
    // 定时器
    private BlockedTimer timer=new BlockedTimer(maxIdle){
        public void onTimer() {
            doBatch();  // 批处理
        }
    };
    public T(){
        timer.start();
    }
    public void putBeat(String rtua, String heartBeatTime) {
        synchronized (object) {
            if (list.size()>batchSize) {
                doBatch();  // 批处理
            }
            list.add(rtua+heartBeatTime);
            /**
             * 如果5秒内没有数据进来,则也做批处理
             */
        }// end
    }
    public void doBatch() {
        timer.reset();  // 重新计时
        synchronized (object){
            //存满batchSize后做批处理
        }
    }
}

#14


昨天后来想想 写了一个

public class T {

    private int batchSize = 8000;    
    private Object object;
    private ArrayList<String> list = new ArrayList<String>();
    long lastTime = System.currentTimeMillis();
    public void putBeat(String rtua, String heartBeatTime) {
        
        synchronized (object) {
            if (list.size()>batchSize) {
                //存满batchSize后做批处理
            }
            list.add(rtua+heartBeatTime);
            lastTime = System.currentTimeMillis();
            /**
             * 如果5秒内没有数据进来,则也做批处理
             */
        }// end
    }
    public boolean disTime(){
long delta = System.currentTimeMillis() - lastTime;
return Math.abs(delta) >= 5*1000 && heartBeatArray.getSize()>0;
    }
    public void add(){
HeartBeatArray batchSaveArray = heartBeatArray;
if (batchSaveArray != null)
     addBatchSaveArray(batchSaveArray);
    }

}

启动线程的时候调用T()
	public void T(){
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
add();
T();
}
public void add() {
// TODO Auto-generated method stub
System.out.println("add:"+System.currentTimeMillis());
if(batchSaver.disTime()){
batchSaver.add();
}
}

#15


引用 4 楼 renmms 的回复:
引用 2 楼 languo 的回复:
线程是一直运行的 有数据进来的时候就插入list 里面


如果是这样,可以在程序外边写个小程序,算时间用的,可以int n,每过一秒自动+1,

然后在程序public void putBeat(String rtua, String heartBeatTime)

里面判断是否n==5,等于5了就操作


支持四楼的想法!

#16


出于性能考虑 应该是间隔时间尽量的长点吧 每秒操作觉得不好

#17


定义一个开始时间和结束时间,相减小于5秒就做操作,直接写在方法里面

#18



class T {

    private int batchSize = 8000;    
    private Object object;
    private ArrayList<String> list = new ArrayList<String>();
    private boolean bBatch;
    
    T()
    {
     startTimer();
    }
    
    public void putBeat(String rtua, String heartBeatTime) {
        
        synchronized (object) {
            if (list.size()>batchSize) {
             batch();
            }
            list.add(rtua+heartBeatTime);
            bBatch = false;
        }
    }
    
    private void batch()
    {
    
    }
    
    public void startTimer()
    {
TimerTask task = new TimerTask()
{
public void run()
{
if(bBatch)
{
batch();
}
else
{
bBatch = true;
}
}
};
new Timer().scheduleAtFixedRate(task, 0,5000);
}
}

#19


我感觉timer.start();
放在putBeat方法里面好一点。

#20


synchronized (object) 上面

#21


多线程调用putBeat 你这样会启动多个timer

#1


没感觉,线程的运行时间本身就不确定,又如何来判断五秒?

#2


线程是一直运行的 有数据进来的时候就插入list 里面

#3


同意1楼

#4


引用 2 楼 languo 的回复:
线程是一直运行的 有数据进来的时候就插入list 里面


如果是这样,可以在程序外边写个小程序,算时间用的,可以int n,每过一秒自动+1,

然后在程序public void putBeat(String rtua, String heartBeatTime)

里面判断是否n==5,等于5了就操作

#5


sleep

#6


还是不懂 刚接触多线程开发

#7


这个在多线程的话,确实不知道怎么加了,不知道你的同步关系

#8


在外部做控制,做一个每个5秒执行的定时器,当执行了putBeat方法时,将记时器重置.若5秒后没有执行方法,则自动执行一次,传入一个null.在你的putBeat方法中判断一下,如果传入的是null的话就不要add到list中

#9


不懂 学习中

#10


定义一个开始时间和结束时间,相减小于5秒就做操作,直接写在方法里面

#11


在后台用一个定时器处理:crontab

#12


引用 8 楼 cosmos1984 的回复:
在外部做控制,做一个每个5秒执行的定时器,当执行了putBeat方法时,将记时器重置.若5秒后没有执行方法,则自动执行一次,传入一个null.在你的putBeat方法中判断一下,如果传入的是null的话就不要add到list中

楼上的方法是可行的,也可以把原来的类也改成一个单独的线程,其他线程add的时候先添加到另外一个列表,然后notify这个线程,由这个单独线程完成add和提交操作,如果是add操作,然后这个单独的线程开始wait,设定为5秒就可以了。

#13


引用 12 楼 fastmask 的回复:
引用 8 楼 cosmos1984 的回复:
在外部做控制,做一个每个5秒执行的定时器,当执行了putBeat方法时,将记时器重置.若5秒后没有执行方法,则自动执行一次,传入一个null.在你的putBeat方法中判断一下,如果传入的是null的话就不要add到list中 
 
楼上的方法是可行的,也可以把原来的类也改成一个单独的线程,其他线程add的时候先添加到另外一个列表,然后notify这个线程,由这个单独线程完成add和提交操作,如果是add操作,然后这个单…


顶!
不太清楚你的业务,简单做一个例子吧,跟上面说的是一个意思. 这里直接把Timer写成了T的一个属性了,根据业务,这个Timer应该是系统唯一的(单例的),你再根据业务调整吧, 不知道是不是你想要的功能.  这里是BlockedTimer的说明:

class T {

    private int batchSize = 8000;    
    private static int maxIdle=5000;
    private Object object;
    private List<String> list = new ArrayList<String>();
    // 定时器
    private BlockedTimer timer=new BlockedTimer(maxIdle){
        public void onTimer() {
            doBatch();  // 批处理
        }
    };
    public T(){
        timer.start();
    }
    public void putBeat(String rtua, String heartBeatTime) {
        synchronized (object) {
            if (list.size()>batchSize) {
                doBatch();  // 批处理
            }
            list.add(rtua+heartBeatTime);
            /**
             * 如果5秒内没有数据进来,则也做批处理
             */
        }// end
    }
    public void doBatch() {
        timer.reset();  // 重新计时
        synchronized (object){
            //存满batchSize后做批处理
        }
    }
}

#14


昨天后来想想 写了一个

public class T {

    private int batchSize = 8000;    
    private Object object;
    private ArrayList<String> list = new ArrayList<String>();
    long lastTime = System.currentTimeMillis();
    public void putBeat(String rtua, String heartBeatTime) {
        
        synchronized (object) {
            if (list.size()>batchSize) {
                //存满batchSize后做批处理
            }
            list.add(rtua+heartBeatTime);
            lastTime = System.currentTimeMillis();
            /**
             * 如果5秒内没有数据进来,则也做批处理
             */
        }// end
    }
    public boolean disTime(){
long delta = System.currentTimeMillis() - lastTime;
return Math.abs(delta) >= 5*1000 && heartBeatArray.getSize()>0;
    }
    public void add(){
HeartBeatArray batchSaveArray = heartBeatArray;
if (batchSaveArray != null)
     addBatchSaveArray(batchSaveArray);
    }

}

启动线程的时候调用T()
	public void T(){
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
add();
T();
}
public void add() {
// TODO Auto-generated method stub
System.out.println("add:"+System.currentTimeMillis());
if(batchSaver.disTime()){
batchSaver.add();
}
}

#15


引用 4 楼 renmms 的回复:
引用 2 楼 languo 的回复:
线程是一直运行的 有数据进来的时候就插入list 里面


如果是这样,可以在程序外边写个小程序,算时间用的,可以int n,每过一秒自动+1,

然后在程序public void putBeat(String rtua, String heartBeatTime)

里面判断是否n==5,等于5了就操作


支持四楼的想法!

#16


出于性能考虑 应该是间隔时间尽量的长点吧 每秒操作觉得不好

#17


定义一个开始时间和结束时间,相减小于5秒就做操作,直接写在方法里面

#18



class T {

    private int batchSize = 8000;    
    private Object object;
    private ArrayList<String> list = new ArrayList<String>();
    private boolean bBatch;
    
    T()
    {
     startTimer();
    }
    
    public void putBeat(String rtua, String heartBeatTime) {
        
        synchronized (object) {
            if (list.size()>batchSize) {
             batch();
            }
            list.add(rtua+heartBeatTime);
            bBatch = false;
        }
    }
    
    private void batch()
    {
    
    }
    
    public void startTimer()
    {
TimerTask task = new TimerTask()
{
public void run()
{
if(bBatch)
{
batch();
}
else
{
bBatch = true;
}
}
};
new Timer().scheduleAtFixedRate(task, 0,5000);
}
}

#19


我感觉timer.start();
放在putBeat方法里面好一点。

#20


synchronized (object) 上面

#21


多线程调用putBeat 你这样会启动多个timer