java 调用java方法中开启新线程是开启了新线程吗

解决Java多线程中11个常见问题_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
解决Java多线程中11个常见问题
源码时代是一家专注于IT职业教育的高科技公...|
总评分0.0|
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩3页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢该问题被发起重新开启投票
投票剩余时间:
之前被关闭原因:
该问题被发起删除投票
投票剩余时间:
距离悬赏到期还有:
参与关闭投票者:
关闭原因:
该问题已经被锁定
锁定原因:()
保护原因:避免来自新用户不合宜或无意义的致谢、跟帖答案。
该问题已成功删除,仅对您可见,其他人不能够查看。
1 如果你是指线程异步通讯,你可以用future,调用get方法来拿到异步执行任务的返回值 2 如果是指并发,可以用java中的线程并发库java.concurrent.*.如下面的几个:
Semaphore:一个计数信号量
ReentrantLock:一个可重入的互斥锁定Lock,功能类似synchronized,但要强大的多。
BlockingQueue:阻塞队列。
CountDownLatch:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。
CountDownLatch主要起倒计时计数器作用,它主要有两个方法await()和countDown()。一旦某个线程调用await()方法,那么该线程就会阻塞,等待CountDownLatch计数器倒计时归零,需要注意的是尽管线程调用await()方法后会阻塞,但是CountDownLatch允许别的线程调用countDown()方法,将计数器减一。也就是说调用计时器的线程阻塞后,可以利用别的线程控制调用线程何时从新开始运行。
这个问题可以理解为进程间通信?线程,应该比进程再容易一些。android中用的是aidl实现进程间通信。handler则可以实现分线程向主线程发送消息。要是单纯java的话?还真没有仔细想过?进程间通信?webService是不是答案呢?线程间通信?java里边main方法是主线程。与其它线程不在同一个线程!通信很难吗?最好把具体问题拿上来。这个问题也太泛泛了。
哥们! 直接上代码~
看你的问题,建议你重新全面考虑线程的设计,此为上策。具体去解决问题是下策。
无论何种级别的运用,跨线程的调度都是后患无穷的做法。程序的易读性几乎没有——对于别人和几周后的你。
这几个答案里, 只有 的回答还算 没有跑题.
一个线程控制另一个线程, 可以使用Thread类的实例方法suspend, stop, resume, destroy等;但是因为不安全, 已经不建议在Java中使用了.
/javase/7/docs/api/java/lang/Thread.html可以看到, suspend, stop, resume, destroy这些可以控制另一个线程的方法, 都已经deprecated了./javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
另外可以使用java.util.concurrent.FutureTask, 可以cancel一个运行中的task.
类似的问题见我的回答
不是您所需,查看更多相关问题与答案
德问是一个专业的编程问答社区,请
后再提交答案
引用至问题
关注该问题的人
共被浏览 (7791) 次博客分类:
&&& 朋友让我帮忙写个程序从文本文档中导入数据到oracle数据库中,技术上没有什么难度,文档的格式都是固定的只要对应数据库中的字段解析就行了,关键在于性能。
&&& 数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis()在最后一个子进程结束后记录当前时间,两次一减得到的时间差即为总共的用时,代码如下
&&&
long tStart = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "开始");//打印开始标记
for (int ii = 0; ii & threadN ii++) {//开threadNum个线程
Runnable r = new Runnable(){
public void run(){
System.out.println(Thread.currentThread().getName() + "开始");
//做一些事情... ...
System.out.println(Thread.currentThread().getName() + "结束.");
Thread t = new Thread(r);
t.start();
System.out.println(Thread.currentThread().getName() + "结束.");//打印结束标记
long tEnd = System.currentTimeMillis();
System.out.println("总共用时:"+ (tEnd - tStart) + "millions");
&&& 结果是几乎在for循环结束的瞬间就执行了主线程打印总共用时的语句,原因是所有的子线程是并发执行的,它们运行时主线程也在运行,这就引出了一个问题即本文标题如何"让主线程等待所有子线程执行完毕"。试过在每个子线程开始后加上t.join(),结果是所有线程都顺序执行,这就失去了并发的意义了,显然不是我想要的。
&&& 网上Google了很久也没有找到解决方案,难道就没有人遇到过这种需求吗?还是这个问题太简单了?无耐只得自己想办法了...
&&& 最后我的解决办法是,自定义一个ImportThread类继承自java.lang.Thread,重载run()方法,用一个List属性保存所有产生的线程,这样只要判断这个List是否为空就知道还有没有子线程没有执行完了,类代码如下:
&&&
public class ImportThread extends Thread {
private static List&Thread& runningThreads = new ArrayList&Thread&();
public ImportThread() {
public void run() {
regist(this);//线程开始时注册
System.out.println(Thread.currentThread().getName() + "开始...");//打印开始标记
//做一些事情... ...
unRegist(this);//线程结束时取消注册
System.out.println(Thread.currentThread().getName() + "结束.");//打印结束标记
public void regist(Thread t){
synchronized(runningThreads){
runningThreads.add(t);
public void unRegist(Thread t){
synchronized(runningThreads){
runningThreads.remove(t);
public static boolean hasThreadRunning() {
return (runningThreads.size() & 0);//通过判断runningThreads是否为空就能知道是否还有线程未执行完
&&& 主线程中代码:
&&&
long tStart = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "开始");//打印开始标记
for (int ii = 0; ii & threadN ii++) {//开threadNum个线程
Thread t = new ImportThread();
t.start();
while(true){//等待所有子线程执行完
if(!ImportThread.hasThreadRunning()){
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + "结束.");//打印结束标记
long tEnd = System.currentTimeMillis();
System.out.println("总共用时:"+ (tEnd - tStart) + "millions");
&&& 打印的结果是:
&&&&&&&&&&& main开始
&&&&&&&&&&& Thread-1开始...
&&&&&&&&&&& Thread-5开始...
&&&&&&&&&&& Thread-0开始...
&&&&&&&&&&& Thread-2开始...
&&&&&&&&&&& Thread-3开始...
&&&&&&&&&&& Thread-4开始...
&&&&&&&&&&& Thread-5结束.
&&&&&&&&&&& Thread-4结束.
&&&&&&&&&&& Thread-2结束.
&&&&&&&&&&& Thread-0结束.
&&&&&&&&&&& Thread-3结束.
&&&&&&&&&&& Thread-1结束.
&&&&&&&&&&& main结束.
&&&&&&&&&&& 总共用时:20860millions
&&& 可以看到main线程是等所有子线程全部执行完后才开始执行的。
&&& ==================================================以下为第二次编辑===============================================
&&& 上面的方法有一个隐患:如果线程1开始并且结束了,而其他线程还没有开始此时runningThreads的size也为0,主线程会以为所有线程都执行完了。解决办法是用一个非简单类型的计数器来取代List型的runningThreads,并且在线程创建之前就应该设定好计数器的值。
&&& MyCountDown类
&&&
public class MyCountDown {
public MyCountDown(int count){
this.count =
public synchronized void countDown(){
public synchronized boolean hasNext(){
return (count & 0);
public int getCount() {
public void setCount(int count) {
this.count =
&&& ImportThread类
&&&
public class ImportThread extends Thread {
private MyCountD
public ImportThread(MyCountDown c) {
public void run() {
System.out.println(Thread.currentThread().getName() + "开始...");//打印开始标记
//Do something
c.countDown();//计时器减1
System.out.println(Thread.currentThread().getName() + "结束. 还有" + c.getCount() + " 个线程");//打印结束标记
&&& 主线程中
&&&
System.out.println(Thread.currentThread().getName() + "开始");//打印开始标记
MyCountDown c = new MyCountDown(threadNum);//初始化countDown
for (int ii = 0; ii & threadN ii++) {//开threadNum个线程
Thread t = new ImportThread(c);
t.start();
while(true){//等待所有子线程执行完
if(!c.hasNext())
System.out.println(Thread.currentThread().getName() + "结束.");//打印结束标记
&&& 打印结果:
&&&&&&&&&&& main开始
&&&&&&&&&&& Thread-2开始...
&&&&&&&&&&& Thread-1开始...
&&&&&&&&&&& Thread-0开始...
&&&&&&&&&&& Thread-3开始...
&&&&&&&&&&& Thread-5开始...
&&&&&&&&&&& Thread-4开始...
&&&&&&&&&&& Thread-5结束. 还有5 个线程
&&&&&&&&&&& Thread-1结束. 还有4 个线程
&&&&&&&&&&& Thread-4结束. 还有3 个线程
&&&&&&&&&&& Thread-2结束. 还有2 个线程
&&&&&&&&&&& Thread-3结束. 还有1 个线程
&&&&&&&&&&& Thread-0结束. 还有0 个线程
&&&&&&&&&&& main结束.
&&& 更简单的方法:使用java.util.concurrent.CountDownLatch代替MyCountDown,用await()方法代替while(true){...}
&&& ImportThread类
&&&
public class ImportThread extends Thread {
private CountDownLatch threadsS
public ImportThread(CountDownLatch threadsSignal) {
this.threadsSignal = threadsS
public void run() {
System.out.println(Thread.currentThread().getName() + "开始...");
//Do somethings
threadsSignal.countDown();//线程结束时计数器减1
System.out.println(Thread.currentThread().getName() + "结束. 还有" + threadsSignal.getCount() + " 个线程");
&&& 主线程中
&&&
CountDownLatch threadSignal = new CountDownLatch(threadNum);//初始化countDown
for (int ii = 0; ii & threadN ii++) {//开threadNum个线程
final Iterator&String& itt = it.get(ii);
Thread t = new ImportThread(itt,sql,threadSignal);
t.start();
threadSignal.await();//等待所有子线程执行完
System.out.println(Thread.currentThread().getName() + "结束.");//打印结束标记
&&& 打印结果:
&&&&&&&&&&& main开始
&&&&&&&&&&& Thread-1开始...
&&&&&&&&&&& Thread-0开始...
&&&&&&&&&&& Thread-2开始...
&&&&&&&&&&& Thread-3开始...
&&&&&&&&&&& Thread-4开始...
&&&&&&&&&&& Thread-5开始...
&&&&&&&&&&& Thread-0结束. 还有5 个线程
&&&&&&&&&&& Thread-1结束. 还有4 个线程
&&&&&&&&&&& Thread-4结束. 还有3 个线程
&&&&&&&&&&& Thread-2结束. 还有2 个线程
&&&&&&&&&&& Thread-5结束. 还有1 个线程
&&&&&&&&&&& Thread-3结束. 还有0 个线程
&&&&&&&&&&& main结束.
浏览 69656
论坛回复 /
(64 / 48383)
干吗不用join?没理解错的话就是主线程等着子线程们结束吧yiyidog125 写道干吗不用join?没理解错的话就是主线程等着子线程们结束吧貌似用join之后,线程之间就变成串行的了,不是并行的了。这样会严重影响效率。
nishizhutoua 写道说句老实话,你确定你的这个需求要用多线程么?
读的方面,瓶颈在IO,用单线程,全速的读就是最快的了.除非你在读取一行数据后要对行数据进行格式化,并且这个格式化时间消耗要大于理论上的连续读两行文本时的CPU时间. 不过恐怕不容易吧,这两个时间差好几个级.
写的部分,瓶颈还是在IO,因为你要写到数据库中.
这么算两个线程就够了,生产者消费者模式即可.
假设有100万条记录,顺序执行的话光是遍历完这100万条记录就要很长时间了,现在开10个线程,每个线程只要插入10万条,是不是会快很多?
看你几块disk,只有一块的话单线顺序程读写就是最快了 磁盘是sequantial access才快的 多线程access pattern被打乱了会慢因为这相当于random access了
import java.util.concurrent.*
然后做该做的事情
oracle导数据还要写程序?
我前面说了因为有xmltype类型的字段,所以想用java先解析一下再插入
这个主题,如果是导入数据到Oracle,用SQL Loader最简单最快,如果在借题发挥到并发多任务,就是一个很大的话题了。好像这篇帖子的内容相关/topic/405492fuermos 写道大数据量,用oralce sqlLoad就行了,都不需要java因为表中有个字段是xmltype型的,插入时需调用oracle的sys.xmltype.createXml()来创建xmltype对象然后插入,这样服务器端压力会很大,所以想用java在客户端创建好XMLType对象,这样服务器端就少了创建xmltype对象的压力了
& 上一页 1
浏览: 140384 次
来自: 上海
感谢楼主,帮到了我
lz活生生地弄了一个线程池啊。。
楼主太给力了~赞一个~~
其实可以使用 ThreadGroup
调用ThreadG ...
何必这么麻烦,其实只需要一个for循环,就可以解决LZ标题问题 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'用户名:zhangjunhd
文章数:110
评论数:893
访问量:3434051
注册日期:
阅读量:1297
阅读量:3317
阅读量:581018
阅读量:465191
51CTO推荐博文
下面的代码展示了在一个方法中,通过匿名内部类定义一个Thread,并Override它的run()方法,之后直接启动该线程。
这样的代码可用于在一个类内部通过另起线程来执行一个支线任务,一般这样的任务并不是该类的主要设计内容。
package com.zj.
public class StartFromMethod {
&&& private Thread t;
&&& private int number;
&&& private int count = 1;
&&& public StartFromMethod(int number) {
&&&&&& this.number =
&&& public void runTask() {
&&&&&& if (t == null) {
&&&&&&&&&& t = new Thread() {
&&&&&&&&&&&&& public void run() {
&&&&&&&&&&&&&&&&& while (true) {
&&&&&&&&&&&&&&&&&&&& System.out.println("Thread-" + number + " run " + count
&&&&&&&&&&&&&&&&&&&&&&&&&&& + " time(s)");
&&&&&&&&&&&&&&&&&&&& if (++count == 3)
&&&&&&&&&&&&&&&&&&&&&&&& return;
&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
&&&&&&&&&& };
&&&&&&&&&& t.start();
&&& public static void main(String[] args) {
&&&&&& for (int i = 0; i & 5; i++)
&&&&&&&&&& new StartFromMethod(i).runTask();
Thread-0 run 1 time(s)
Thread-0 run 2 time(s)
Thread-1 run 1 time(s)
Thread-1 run 2 time(s)
Thread-2 run 1 time(s)
Thread-2 run 2 time(s)
Thread-3 run 1 time(s)
Thread-3 run 2 time(s)
Thread-4 run 1 time(s)
Thread-4 run 2 time(s)本文出自 “” 博客,请务必保留此出处
了这篇文章
附件下载:  
类别:┆阅读(0)┆评论(0)
请输入验证码:

我要回帖

更多关于 java多线程异步调用 的文章

 

随机推荐