一个线程接收不定时发来的网络发来的包,存在List<Packet>里,另一个线程从list里取出包解析,并移除,并将其存入数据库,每50个批处理一次,接收线程收到包抓包程序回调就可以向list里添加 解析线程主动从list取 如果取空了就得死循环 while(true)检测list.size何时大于0 
  但我不想死循环检测 问:能不能当第一个线程有新包来时 通知第二个线程 notifyAll 或 singalAll会唤醒哪个线程不确定 notify 或 singal 也不确定。只开两个线程可能都是解析线程(线程池executor),不用线程池的话如何让执行完的线程再重复执行 new Thread的话先的线程可能还没执行完
  以下模拟有问题的代码 注释中也提出疑问 是不是不该多个线程共用一个PrepareStatment(未同步)
package test;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadDao { public static void main(String[] args) throws Exception {
Dao dao=new Dao();
dao.conn();
ExecutorService pool = Executors.newFixedThreadPool(2);

for(int i=0;i<100;i++){//模拟网络发来的100个包
pool.execute(new Runnable() {

@Override
public void run() {
System.out.print("c");

}
});//模拟接受包 是不是应该放到循环100次外面?
pool.execute(new Parse(dao));//取出解析包  是不是应该放到循100次外面? }
}
}
class Parse implements Runnable{
public Dao dao; public Parse(Dao dao) {
this.dao = dao;
} @Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(500);
dao.save();//可能有2个线程同时访问同一个dao对象
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Dao{
static int cnt=0;
PreparedStatement ps;Connection c;
public void conn() throws Exception{
Class.forName("com.mysql.jdbc.Driver");
c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test","","");
c.setAutoCommit(false);
ps = c.prepareStatement("insert into u values(?)");
}

public void save() throws Exception{
ps.setInt(1, 33);
ps.addBatch();//可能有2个线程同时访问同一个ps对象 结果容易出错
cnt++;
if(cnt%50==0){
ps.executeBatch();
c.commit();
ps.clearBatch();
}
// Thread.sleep(500);
}
}

解决方案 »

  1.   

    给你随便找了个例子 http://www.javacodegeeks.com/2011/09/java-concurrency-tutorial-semaphores.html
      

  2.   

    你是否要异步处理问题?如果采用事件模式,则要等到事件处理完后才会进入下一步。
    还是采用同步方法吧。read() {
    operate(data, 1);
    }send() {
    operate(data, 2);
    }synchronized operate(data, type) {
        // 读
        if (type == 1) {
        } else if (type == 2) { // 送
        }
    }我只是随便写一下,读到数据,存到List后,就可以继续读下一个数据了。
    这样的同步并发还是挺高的,我测试过线程来读与送,能达到4W多并发执行,应该不存在这里阻塞你的执行。
    待高人帮你提出更优解决方案。
      

  3.   

    好像是要接收和解析异步 因为网上发来的udp包数据量很大 udp只管发 要先接收把它存(添加)到list里 然后解析线程再慢慢的去读