论坛首页 Java企业应用论坛

Java多线程--让主线程等待所有子线程执行完毕

浏览 54828 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-01-28  
srdrm 写道
用多线程导入是失败的设计

这个算不上是失败,设计好了话也可以提高效率,但是不推荐这是首选方案。
0 请登录后投票
   发表时间:2010-01-28  
zli.ray 写道
又一个轮子。
用java.util.concurrent.CountDownLatch就可以了。

即使在1.4中,CountDownLatch用不了,lz的代码里主线程的while循环中,至少应该sleep一下,不然很耗吧。

同意。
感觉设置一个线程计数器,主线程先wait(),子线程执行完毕操作计数器,并判断是否需要notify()。似乎也可以实现。
0 请登录后投票
   发表时间:2010-01-28  
用FileChinnel 锁定文件的不同块,然后通过MapByteBuffer做内存映射文件,然后多线程处理

前提是要有大的内存
也可以分步
0 请登录后投票
   发表时间:2010-01-28   最后修改:2010-01-28
zli.ray 写道
蓝皮鼠 写道
java的线程缺省行为就是主线程要等待所有线程完成才退出啊,不知道楼主为什么要提这个问题

模拟的场景为,在所有子线程都执行完毕后,主线程要做一些事情,比如记录时间戳等等。

这种情况用如下方法不是更简单么
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				// 做你的事情。。。;
			}
		});


建议大家仔细的学习JDK自己提供的方法。。
0 请登录后投票
   发表时间:2010-01-28   最后修改:2010-01-28
试着写了一个似乎和楼主需求相关的代码,请大家批评一下,是否合理。
主要是使用wait和notity来进行处理这种多个线程的问题。另外,对于其它一些多线程问题,可以使用jdk5.0中的concurrency包下的API,很好用的。Executor,Furture,Callable,在外网查一下这几个关键定,就有很多相关说明。对于控制线程的所有问题,它们都是那么的好用及稳健。
import java.util.ArrayList;
import java.util.List;

public class ThreadMain {
	public static void main(String[] args) {
		long currentTime = System.currentTimeMillis();
		CountTool countTool = new CountTool();
		List<Runnable> taskList = new ArrayList<Runnable>();
		taskList.add(new MayTask(countTool, 1)); //1代表秒
		taskList.add(new MayTask(countTool, 2));
		taskList.add(new MayTask(countTool, 3));
		taskList.add(new MayTask(countTool, 4));
		countTool.start(taskList);
		System.out.println("I am main thread, after others is ok. time is " + (System.currentTimeMillis()-currentTime));
	}
}
/**
 *启动任务,并管理任务是否都已经完成 
 */
class CountTool {
	private Object ob = new Object();
	
	private int countNum;
	private int countNumDest;
	public CountTool() {
	}
	/**
	 *主线程调用,将任务对象放到一个列表中,在方法每个任务创建一个线程执行任务
	 *如果执行完成后,执行结果完成数加1,并且判断是否已经达到执行完成的总数,是则唤醒主线程
	 * @param <T>
	 * @param task
	 */
	public void start(List<Runnable> taskList) {
		countNum = taskList.size();
		synchronized (ob) {
			for (Runnable task : taskList) {
				new Thread(task).start();
			}
			try {
				ob.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	public void oneOk() {
		synchronized (ob) {
			if (++countNumDest >= countNum) {
			    ob.notify();
			}
		}
	}
}
/**
 * 具体执行任务
 */
class MayTask implements Runnable{
	private CountTool countTool;
	private int sleepTime;
	public MayTask(CountTool countTool, int sleepTime) {
		this.countTool = countTool;
		this.sleepTime = sleepTime * 1000;
	}
	public void run() {
		try {
			System.out.println("Current thread name is" + Thread.currentThread().getName() + "i will sleep " + sleepTime);
			Thread.currentThread().sleep(sleepTime);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		countTool.oneOk();
	}
}

0 请登录后投票
   发表时间:2010-01-29   最后修改:2010-01-29
ExecutorService exec = Executors.newFixedThreadPool(10);
for ( ... )
    exec.execute( new Task(...) );

exec.shutdown();
try {
    exec.awaitTermination(5 * 60 * 60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}
0 请登录后投票
   发表时间:2010-01-29  
zhangdp_neu 写道
srdrm 写道
用多线程导入是失败的设计

这个算不上是失败,设计好了话也可以提高效率,但是不推荐这是首选方案。

用多线程主要是因为数据库中有xmltype类型的字段,会比较引响性能,现在看来还没有达到预期目的,现在导20w条耗时20秒左右,有没有人知道如何处理xmltype类型字段?谢了
0 请登录后投票
   发表时间:2010-01-29   最后修改:2010-01-29
蓝皮鼠 写道
zli.ray 写道
蓝皮鼠 写道
java的线程缺省行为就是主线程要等待所有线程完成才退出啊,不知道楼主为什么要提这个问题

模拟的场景为,在所有子线程都执行完毕后,主线程要做一些事情,比如记录时间戳等等。

这种情况用如下方法不是更简单么
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				// 做你的事情。。。;
			}
		});


建议大家仔细的学习JDK自己提供的方法。。

呵呵,还有这种巧妙地用法,受教!
不过,看了一下addShutdownHook的javadoc,感觉它有一些局限性。
addShutdownHook添加的关闭挂钩,是在java虚拟机关闭前执行,但是,有些时候,子线程运行完毕后,并不期望程序退出,可能还有其它的任务,甚至有可能程序是一个长时间运行的服务器,那就更不可能随便停止了。这种情况下,关闭挂钩就无能为力了,而CountDownLatch则没有这种限制,较之灵活性更强。不知理解的对不对。
0 请登录后投票
   发表时间:2010-01-29   最后修改:2010-01-29

看看我是怎么实现的
http://henryyu.iteye.com/admin/blogs/374304

 

0 请登录后投票
   发表时间:2010-01-29  
说句老实话,你确定你的这个需求要用多线程么?
读的方面,瓶颈在IO,用单线程,全速的读就是最快的了.除非你在读取一行数据后要对行数据进行格式化,并且这个格式化时间消耗要大于理论上的连续读两行文本时的CPU时间. 不过恐怕不容易吧,这两个时间差好几个级.
写的部分,瓶颈还是在IO,因为你要写到数据库中.
这么算两个线程就够了,生产者消费者模式即可.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics