论坛首页 Java企业应用论坛

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

浏览 54582 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-01-28  
java线程是能并发了!
oracle数据库是并发入库的吗。
0 请登录后投票
   发表时间:2010-01-28  
srdrm 写道
难道不会变通一下?

你是 for 循环中,start, join 一起来, 你不会改为只 start thread, 同时将thread保存起来. 全部 start 完毕后再一个个join, 甚至带上时间 join(1000)



受教,确实是这样。最开始以为自己的想法是错误的,原来start -> join, start -> join这样是确实相当于一个个顺序执行。

如果是startA,startB, joinA,joinB确实能实现同样的功能
0 请登录后投票
   发表时间:2010-01-28  
java的线程缺省行为就是主线程要等待所有线程完成才退出啊,不知道楼主为什么要提这个问题
0 请登录后投票
   发表时间:2010-01-28  
蓝皮鼠 写道
java的线程缺省行为就是主线程要等待所有线程完成才退出啊,不知道楼主为什么要提这个问题

模拟的场景为,在所有子线程都执行完毕后,主线程要做一些事情,比如记录时间戳等等。
0 请登录后投票
   发表时间:2010-01-28  
火车头那本书 《JAVA并发编程实践》里面讲了闭锁的用法,可以看一下
0 请登录后投票
   发表时间:2010-01-28  
oaklet 写道
java线程是能并发了!
oracle数据库是并发入库的吗。


去好好学习一下Oracle的并行度机制
0 请登录后投票
   发表时间:2010-01-28   最后修改:2010-01-28
    有一个个人观点:第一个版本的声明为static的类变量runningThreads的访问并不是线程安全的,代码:
public synchronized void regist(Thread t){  
 runningThreads.add(t);
}

这个synchronized的作用是使用ImportThread实例的锁,而不是类对象的锁,所以主线程中:
for (int ii = 0; ii < threadNum; ii++) {//开threadNum个线程  
 Thread t = new ImportThread();  
 t.start();  
}

进入regist()方法几乎是同时的,也就是对runningThreads的操作几乎是同时的。因为每个线程都是获得自己实例的锁,没有任何竞争关系,这就在高并发的情况下使得ArrayList的结构可能被破坏。可以通过实验代码测试:
public synchronized void regist(Thread t){
 System.out.println(Thread.currentThread().getName() + " will sleeping.");
 try {
     Thread.sleep(3000);
 }
 catch (InterruptedException e) {
     e.printStackTrace();
 }
 runningThreads.add(t);
}

这里可以看到持有锁的线程进入睡眠时并没有排斥其他线程的进入,也就是主程序启动的子线程之间并不构成竞争,打印语句几乎同时执行。所以要想使得类变量被安全的访问要在所有的访问方法上使用类对象的锁,也就是所有相应的方法使用public static synchronized声明。这样所有的子线程在访问runningThreads的时候会竞争类对象的锁,达到对类变量的安全访问。
    以上仅个人观点,仅供参考。
0 请登录后投票
   发表时间:2010-01-28  
"关键在于性能" 的话,你就直接Oracle的SQLLoader方式导入,这个很快。

如果你一定要用多线程导入的话,最好针对你的线程个数设置多个 Freelist。
有助于较少锁的争用。
0 请登录后投票
   发表时间:2010-01-28  
ftj20003 写道
    有一个个人观点:第一个版本的声明为static的类变量runningThreads的访问并不是线程安全的,代码:
public synchronized void regist(Thread t){  
 runningThreads.add(t);
}

这个synchronized的作用是使用ImportThread实例的锁,而不是类对象的锁,所以主线程中:
for (int ii = 0; ii < threadNum; ii++) {//开threadNum个线程  
 Thread t = new ImportThread();  
 t.start();  
}

进入regist()方法几乎是同时的,也就是对runningThreads的操作几乎是同时的。因为每个线程都是获得自己实例的锁,没有任何竞争关系,这就在高并发的情况下使得ArrayList的结构可能被破坏。可以通过实验代码测试:
public synchronized void regist(Thread t){
 System.out.println(Thread.currentThread().getName() + " will sleeping.");
 try {
     Thread.sleep(3000);
 }
 catch (InterruptedException e) {
     e.printStackTrace();
 }
 runningThreads.add(t);
}

这里可以看到持有锁的线程进入睡眠时并没有排斥其他线程的进入,也就是主程序启动的子线程之间并不构成竞争,打印语句几乎同时执行。所以要想使得类变量被安全的访问要在所有的访问方法上使用类对象的锁,也就是所有相应的方法使用public static synchronized声明。这样所有的子线程在访问runningThreads的时候会竞争类对象的锁,达到对类变量的安全访问。
    以上仅个人观点,仅供参考。

是的,锁应该加在参数Thread t上或者方法是static的,谢谢
0 请登录后投票
   发表时间:2010-01-28  
yadsun 写道
ftj20003 写道
    有一个个人观点:第一个版本的声明为static的类变量runningThreads的访问并不是线程安全的,代码:
public synchronized void regist(Thread t){  
 runningThreads.add(t);
}

这个synchronized的作用是使用ImportThread实例的锁,而不是类对象的锁,所以主线程中:
for (int ii = 0; ii < threadNum; ii++) {//开threadNum个线程  
 Thread t = new ImportThread();  
 t.start();  
}

进入regist()方法几乎是同时的,也就是对runningThreads的操作几乎是同时的。因为每个线程都是获得自己实例的锁,没有任何竞争关系,这就在高并发的情况下使得ArrayList的结构可能被破坏。可以通过实验代码测试:
public synchronized void regist(Thread t){
 System.out.println(Thread.currentThread().getName() + " will sleeping.");
 try {
     Thread.sleep(3000);
 }
 catch (InterruptedException e) {
     e.printStackTrace();
 }
 runningThreads.add(t);
}

这里可以看到持有锁的线程进入睡眠时并没有排斥其他线程的进入,也就是主程序启动的子线程之间并不构成竞争,打印语句几乎同时执行。所以要想使得类变量被安全的访问要在所有的访问方法上使用类对象的锁,也就是所有相应的方法使用public static synchronized声明。这样所有的子线程在访问runningThreads的时候会竞争类对象的锁,达到对类变量的安全访问。
    以上仅个人观点,仅供参考。

是的,锁应该加在参数Thread t上或者方法是static的,谢谢

sorry,是加在runningThreads上
0 请登录后投票
论坛首页 Java企业应用版

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