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