线程

时间:2018-04-15 13:48:18

标签: java multithreading javafx jdbc concurrency

我正在开发一个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;
}

getEmployerByNo方法

public synchronized Employer getEmployerByNo( String no_emp ) throws DAOException {
    Employeur emp = null;
    Connection con = null;
    PreparedStatement stm = null;
    ResultSet res = null;
    try{
        con = dao.getConnection();
        stm = preparedRequestInitialisation( con, GET_BY_NO_SQL, no_emp );
        res = stm.executeQuery();
        if( res.next() ){
        //map is a function that map the database resultset data with the object properties
            emp = map( res );
            LOG.info( "getting the employer : "+ no_emp );
        }
    } catch( SQLException e ){
        throw new DAOException( e.getLocalizedMessage() );
    } finally{
        silentClose( res, stm, con );
    }
    return emp;
}

1 个答案:

答案 0 :(得分:0)

根据需要使用ExecutorServiceFuture.get()等待完成。请参阅文档herehere。这是一个或多或少完整的例子:

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

}