Java DAO与线程间的同步

Java DAO与线程间的同步,java,multithreading,javafx,jdbc,concurrency,Java,Multithreading,Javafx,Jdbc,Concurrency,我正在开发一个Javafx应用程序,它同步来自两个不同数据库的一些数据。 在call方法中,我获取所有数据并将其存储在ArrayList中。然后我循环遍历ArrayList,并尝试从第二个数据库获取相同的数据。 如果存在,我会比较差异,如果存在差异,我会更新。否则,如果它不存在,我将通过DAO对象方法插入它。 问题是,有时第二个数据库需要一些时间来提供响应,因此进程将继续执行,新数据将与旧数据进行比较。 我的问题是,如何停止进程,直到所有数据都已提取,然后继续执行同步逻辑 @Override p

我正在开发一个Javafx应用程序,它同步来自两个不同数据库的一些数据。 在call方法中,我获取所有数据并将其存储在
ArrayList
中。然后我循环遍历
ArrayList
,并尝试从第二个数据库获取相同的数据。 如果存在,我会比较差异,如果存在差异,我会更新。否则,如果它不存在,我将通过DAO对象方法插入它。 问题是,有时第二个数据库需要一些时间来提供响应,因此进程将继续执行,新数据将与旧数据进行比较。 我的问题是,如何停止进程,直到所有数据都已提取,然后继续执行同步逻辑

@Override
protected Map call() throws Exception {
    Map<String, Integer> m = new HashMap();
    updateTitle( "getting the data ..." );
    int i, updated = 0, inserted = 0;
    // creating first database instance
    DAOFactory db1Dao = DAOFactory.getInstance( "db1" );
    //creating the first database dataObject instance
    Db1EmployerDAO empDb1Dao = db1Dao.getDAODb1Employer();
    // creating second database instance
    DAOFactory db2Dao = DAOFactory.getInstance( "db2" );
    //creating the second database dataObject instance
    Db2EmployeurDAO empDb2Dao = db2Dao.getDAODb2Employer();
    Employer emp;
    // getting all the object
    List< Employer > LEmpDb1 = empDb1Dao.getAll();
    updateTitle( "Data proccessing ..." );
    //for each data in the list
    for( i = 1; i <= LEmpDb1.size(); i++ ){
        if( isCancelled() )
            break;
        updateMessage( "Processing employer : "+ LEmpDb1.get( i-1 ).getNemploy() +" "+ LEmpDb1.get( i-1 ).getRaison() );

    //trying to get the object from the second database which the
    //process sometimes pass befor the result is getting which is my problem
        emp = empDb2Dao.getEmployerByNo( LEmpDb1.get( i-1 ).getNemploy() );
        if( emp != null){
            if( !LEmpDb1.get( i-1 ).equals( emp ) )
                if( empDb2Dao.update( LEmpDb1.get( i-1 ) ) ){
                    updated++;
                    LOG.log( "MAJ employeur : "+  LEmpDb1.get( i ).getNemploy()+" => "+LEmpDb1.get( i ).getDifferences( emp ) );
                }
        } else {
            if( empDb2Dao.insert( LEmpDb1.get( i-1 ) ) )
                inserted++;
        }
        updateProgress( i, LEmpDb1.size() );
    }
    m.put( "upd", updated );
    m.put( "ins", inserted );
    m.put( "all", LEmpDb1.size() );
    return m;
}

根据需要使用
ExecutorService
Future.get()
等待完成。请参阅文档和。以下是一个大致完整的示例:

public class Application implements Runnable {

    private final ExecutorService pool = Executors.newCachedThreadPool();

    public void run() {
        Dao firstDao = new DaoImpl();
        Dao secondDao = new AnotherDaoImpl();

        FetchAllTask fetchAll = new FetchAllTask(firstDao);
        Future<?> fetchAllFuture = pool.submit(fetchAll);
        try {
            fetchAllFuture.get();
        } catch (Exception e) {
            // TODO handle
            System.out.println("An exception occurred!");
            e.printStackTrace();
        }
        ConcurrentSkipListSet<AnObject> items = fetchAll.getItems();
        Iterator<AnObject> it = items.iterator();
        while (it.hasNext()) {
            // insert your cancellation logic here
            // ...
            AnObject daoObj = it.next();
            FetchOneTask fetchOne = new FetchOneTask(secondDao, daoObj.getId());
            Future<?> fetchOneFuture = pool.submit(fetchOne);
            try {
                fetchOneFuture.get();
                AnObject anotherDaoObj = fetchOne.getAnObject();
                if (anotherDaoObj == null) {
                    // the object retrievied by the first dao (first datasource)
                    // is not in the second; it needs to be inserted into the second
                    System.out.println(String.format("Inserting %s", daoObj));
                    secondDao.insert(daoObj);
                } else {
                    System.out.println(String.format("Updating %s to %s", anotherDaoObj, daoObj));
                    secondDao.update(daoObj);
                }
            } catch (Exception e) {
                System.out.println("An exception occurred!");
                e.printStackTrace();
            }
        }

        Set<AnObject> itemsInSecondDb = secondDao.fetchAll();
        for (AnObject o : itemsInSecondDb) {
            System.out.println(o);
        }

        pool.shutdown();
    }

    // ... invoke the app thread from somewhere else

}
公共类应用程序实现可运行{
私有最终执行器服务池=Executors.newCachedThreadPool();
公开募捐{
Dao firstDao=新的DaoImpl();
Dao secondDao=新的另一个daoimpl();
FetchAllTask fetchAll=新的FetchAllTask(firstDao);
Future fetchAllFuture=pool.submit(fetchAll);
试一试{
fetchAllFuture.get();
}捕获(例外e){
//待办事项处理
System.out.println(“发生异常!”);
e、 printStackTrace();
}
ConcurrentSkipListSet items=fetchAll.getItems();
Iterator it=items.Iterator();
while(it.hasNext()){
//在此处插入取消逻辑
// ...
AnObject daoObj=it.next();
FetchOneTask fetchOne=新的FetchOneTask(secondDao,daoObj.getId());
Future fetchOneFuture=pool.submit(fetchOne);
试一试{
fetchOneFuture.get();
AnObject anotherDaoObj=fetchOne.getAnObject();
if(另一个daoobj==null){
//第一个dao(第一个数据源)检索的对象
//不在第二个中;需要将其插入第二个中
System.out.println(String.format(“插入%s”,daoObj));
第二个DAO.insert(DAOBJ);
}否则{
System.out.println(String.format(“将%s更新为%s”,另一个daoObj,daoObj));
更新(daoObj);
}
}捕获(例外e){
System.out.println(“发生异常!”);
e、 printStackTrace();
}
}
Set itemsinsseconddb=secondDao.fetchAll();
对于(对象o:itemsInSecondDb){
系统输出打印ln(o);
}
pool.shutdown();
}
//…从其他地方调用应用程序线程
}
public class Application implements Runnable {

    private final ExecutorService pool = Executors.newCachedThreadPool();

    public void run() {
        Dao firstDao = new DaoImpl();
        Dao secondDao = new AnotherDaoImpl();

        FetchAllTask fetchAll = new FetchAllTask(firstDao);
        Future<?> fetchAllFuture = pool.submit(fetchAll);
        try {
            fetchAllFuture.get();
        } catch (Exception e) {
            // TODO handle
            System.out.println("An exception occurred!");
            e.printStackTrace();
        }
        ConcurrentSkipListSet<AnObject> items = fetchAll.getItems();
        Iterator<AnObject> it = items.iterator();
        while (it.hasNext()) {
            // insert your cancellation logic here
            // ...
            AnObject daoObj = it.next();
            FetchOneTask fetchOne = new FetchOneTask(secondDao, daoObj.getId());
            Future<?> fetchOneFuture = pool.submit(fetchOne);
            try {
                fetchOneFuture.get();
                AnObject anotherDaoObj = fetchOne.getAnObject();
                if (anotherDaoObj == null) {
                    // the object retrievied by the first dao (first datasource)
                    // is not in the second; it needs to be inserted into the second
                    System.out.println(String.format("Inserting %s", daoObj));
                    secondDao.insert(daoObj);
                } else {
                    System.out.println(String.format("Updating %s to %s", anotherDaoObj, daoObj));
                    secondDao.update(daoObj);
                }
            } catch (Exception e) {
                System.out.println("An exception occurred!");
                e.printStackTrace();
            }
        }

        Set<AnObject> itemsInSecondDb = secondDao.fetchAll();
        for (AnObject o : itemsInSecondDb) {
            System.out.println(o);
        }

        pool.shutdown();
    }

    // ... invoke the app thread from somewhere else

}