新人庸人自扰,纠结此问题数日,求高人明示。请问高人,JAVA里面有没得啥子办法把一个子线程暂停,然后返回主线程执行另外一个子线程,然后另外一个子线程又暂停,继续执行先前那个被暂停的子线程(此时第一个子线程接着执行完被暂停时未执行完的代码),等第一个子线程执行完了,再接着执行完被暂停的第二个子线程(同理,这第二个子线程也是继续执行刚被挂起前未被执行完的代码),然后返回主线程继续执行主线程的代码。注: 第一个子线程和第二个子线程都是非循环执行的,也就是说,第一个子线程和第二个子线程只执行一次。就是说怎么暂停一个正在执行代码的子线程,并且让其恢复后,接着执行剩下的代码,而不是又重头执行一次,我意思是只接着执行因为暂停而未执行的剩下那部分的代码。谢谢高人解答,困惑我许久啊!!! (sleep尝试过,但是貌似那个太不可控,往往是第一个子线程醒来第二个还没开始执行。我就想了解下如何用可控的手段,让两个并发的子线程,通过主线程中转,互相暂停各自的一部分,然后接着执行各自剩下的一部分)唉,用语不太科学准确,还请高人海涵。谢谢!
yield()
暂停当前正在执行的线程对象,并执行其他线程
此flag来自主线程里面一个public static。不知道得行不?
第一个线程运行一会,然后sleep,同时notifyAll其他线程
第二个线程运行一会后也sleep,同时notifyAll第一个线程
第一个线程继续运行,结束时notifyAll第二个线程
(thread)a.start() }
这个是没问题的,但是,如果试图在b里面调用 a.wait() ,即阻塞b线程来执行a线程的代码就会出错
我查了信息,发现主线程是可以通过调用: main thread{ a.wait() ;} 来使a 中断主线程来执行a这个子线程的代码,然后待a子线程执行完它的代码后再返回主线程。我尝试将以上思想反过来用,即:thread a {
wait();
....
....
}
我想 中断a子线程,然后返回执行主线程,但是这样就死锁了。。a这个子线程一自我wait()就回不去了,自己把自己搞死了。。
看来这种思路不能反起用,那么,JAVA里面有什么机制能够实现子线程自我调用或者其他线程调用方法来暂停它,转而执行其他线程,然后还能够醒过来 接着“执行暂停前未执行的代码”(非重新开始执行)还是困惑不已啊
再次感谢楼上的这些热心高人,祝福你们!
首先是尝试在子线程c中调用b.wait() 来使b中断线程c的执行,转而执行线程b
(thread)c
{
synchronized(this){
System.out.println("this is threadC");
try
{b.start();
System.out.println("Waiting for c to run...");
b.wait();
System.out.println("C has Completed.Now back to main thread");
}catch (InterruptedException e){e.printStackTrace();}
notifyAll();
}
然后我执行线程b ,希望通过线程b的执行完成来唤醒线程c(thread)b
{
synchronized(this)
{
System.out.println("thread b"+"is waking up");
System.out.println("ThreadB is running..");
notifyAll();
}
}
}得到的结果是, b线程确实执行完了,C线程也确实在b.wait()处暂停了,但是,b线程调用的notifyAll()并没有唤醒阻塞状态的c,而是继续返回执行主线程,就是说c没有继续执行下去。并且还报错: at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at ThreadC.run(ThreadC.java:23) //这个位置就是b.wait() 这句话的位置。
Thread c = new Thread(new ThreadC());
c.start();
}
}class ThreadC implements Runnable { public void run() { Thread b = new Thread(new ThreadB()); // 以对象 b 作为锁,这里的对象 b 也就是在 ThreadB 线程中 this 对象
synchronized (b) {
System.out.println("this is threadC"); // 启动 b 线程,由于 b 线程中使用 this,也就是这个 b 对象作为锁,因此 b.start()
// 中的代码并不会马上执行,而需要等待到这个线程将 b 对象锁释放掉
b.start(); System.out.println("Waiting for c to run...");
try { // 在 b 对象锁上进行等待,等待的同时将 b 锁释放给其他线程用,此时 C 线程在此一直阻塞。
// 当在其他线程中执行了 b.notifyAll() 时会将其唤醒,该线程会等待 b 对象锁重新锁定代码块,
// 执行下面的代码
b.wait(); System.out.println("C has Completed.Now back to main thread");
} catch (InterruptedException e) {
// // 可能在什么地方执行了 Thread.currentThread().interrpt() 方法会抛出此异常
e.printStackTrace();
}
}
}
}class ThreadB implements Runnable { @Override
public void run() { // 使用当前对象作为锁,锁住代码块
// 被锁住的代码只能在 C 线程中释放了 b 对象锁(执行到 b.waite() 方法后),这里才有机会执行,
synchronized (this) {
System.out.println("thread b is waking up");
System.out.println("ThreadB is running.."); // 唤醒所有在这个对象上等待的线程
// 当然了,要其他等待着的线程运行,需要这个线程运行完后释放当前对象锁,其他等待
// 中的线程才有机会重新获得这个对象的锁
notifyAll(); System.out.println("after ThreadB notifyAll");
}
}
}
祝福这位好心的大哥!好人一生平安,事业有成!!
再次感谢bao110908大哥!
大哥所言甚是,当时我用synchronized (this),是想的是如果多个线程同时在执行这段代码的时候,只能当前的一个线程拿到锁,没想到如果后面指定了是b调用wait(),前面synchronized () 就要变成synchronized (b)纠结了这么多天的问题啊。看来凡事都该上上CSDN问,还是好人多啊。哈哈