我有以下示例代码,
public class test implements Runnable{
public void run()
{
synchronized(this)
{
for(int i=0;i<10000;i++)
System.out.println(i);
}
}
public static void main(String args[]) throws Exception
{
Thread t=new Thread(new test());
t.start();
//Thread.sleep(100);
t.suspend();
System.out.println("Hi");
}
}
我有以下要求,当线程被挂起时,它必须执行循环的所有迭代而不会被挂起。我觉得同步是为了这个目的,但它没有解决问题。当我挂起一个线程(如果它在同步块中)时,它必须在块执行后才被挂起。可以使用什么java构造?
答案 0 :(得分:0)
在Java中,当一段代码在synchronized
块中时,只有一个线程可以一次执行该块。为了在线程完成其同步块之后暂停线程,只需在同一个变量上同步:
public class Test implements Runnable {
public void run() {
synchronized(this) {
// some work
}
}
public static void main(String args[]) throws Exception {
Test target = new Test();
Thread t = new Thread(target);
t.start();
synchronized(target) {
t.suspend();
}
System.out.println("Hi");
}
}
请注意,run()
和main()
中的两个块都在同一个变量(Test
的实例)上同步。现在main()
中同步块中的代码只有在run()
中的工作完成后才会执行。
(但请注意,这里存在一些竞争条件:t.start()
之后run()
中的代码将在main()
中的下一行代码之前实际执行后,您无法保证
答案 1 :(得分:0)
suspend()
暂停线程的执行权。从程序代码执行此操作通常不是一个好主意,因为该线程仍将保留任何监视器,锁,资源等。
相反,使用在您不希望执行时阻止该线程的同步原语。例如,信号量可用于使线程等待:
public class test implements Runnable{
final Semaphore semaphore = new Semaphore();
public void run()
{
synchronized(this)
{
for(int i=0;i<10000;i++)
System.out.println(i);
semaphore.acquire(); // possibly block on the semaphore
semaphore.release(); // release our lock, we don't need it anymore
}
}
public void suspend()
{
semaphore.acquire();
}
public void resume()
{
semaphore.release();
}
}
public static void main(String args[]) throws Exception
{
Test test = new test());
Thread thread = new Thread(test);
thread.start();
// at some point in the future you want to pause execution
test.suspend();
// hi will either appear before all of Test's output, or after. but not inbetween.
System.out.println("Hi");
test.resume();
}
您也可以使用Locks和Condition来实现相同的功能,但代码稍微多一点,所以我们在这里使用Semaphore来保持简单。
通过不直接挂起线程,而是阻塞它,你可以使用Executors,ThreadPools和其他类型的线程管理(例如ForkJoinPool,SwingWorker等)。