我有一个多线程程序,它按顺序strs
次排序线程。每个线程都有自己的监视器。此线程的一个监视器(lock
)和后一个线程的另一个监视器(unlock
)将传递给每个线程的构造函数。首先,当每个线程启动时,它必须在array[0] != this
时停止,但如果我在第13行写入,则会出现死锁。所以我使用Threads.count,每次迭代都会增加。这样程序就可以了。你能告诉我为什么会这样吗?
class Foo extends Thread
{
private Object lock, unlock;
Foo(Object lock, Object unlock)
{
this.lock = lock;
this.unlock = unlock;
}
public void run()
{
synchronized(lock)
{
if(Threads.array[Threads.count] != this) // line 13!!!
{
waiter();
}
for(int i = 0; i < Threads.strs; ++i)
{
if(Threads.array[0] == this)
{
System.out.println(i+1);
}
System.out.print(getName() + ' ');
++Threads.count;
if(Threads.array[Threads.thrs-1] == this)
{
System.out.println();
}
if(unlock != lock)
{
synchronized(unlock)
{
unlock.notify();
}
waiter();
}
}
}
}
void waiter()
{
try
{
lock.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
System.exit(1);
}
}
}
public class Threads
{
public static Thread array[];
public static Object lock[];
public static int count, strs, thrs;
public static void main(String args[])
{
thrs = 0;
strs = 0;
count = 0;
try
{
assert(args.length == 2);
thrs = Integer.parseInt(args[0]);
strs = Integer.parseInt(args[1]);
assert((thrs > 0) && (strs > 0));
}
catch(NumberFormatException | AssertionError e)
{
System.out.println("Uncorrect enter!");
System.exit(1);
}
lock = new Object[thrs];
array = new Thread[thrs];
for(int i = 0; i < thrs; ++i)
{
lock[i] = new Object();
}
for(int i = 0; i < thrs; ++i)
{
if(i != thrs-1)
{
array[i] = new Foo(lock[i],lock[i+1]);
}else
{
array[i] = new Foo(lock[i],lock[0]);
}
array[i].start();
}
}
}
答案 0 :(得分:0)
第13行基本上说“等待前一个线程通知,除非我是第一个线程”。这是有道理的:从我从代码中可以看出,你希望线程按照你创建线程的顺序逐个完成它们的任务(哪种方式违背了使用线程的目的,但这是另一个故事) 。
另请注意,程序不会退出,因为所有线程都在循环结束时调用waiter()
。
所以解决方案很简单:让所有线程在循环开始时等待,但是在创建所有线程之后,触发第一个线程开始运行(这反过来会触发其他线程开始运行)。在我稍微调整的代码副本下面,我提到了两个更改:
class ThreadsInSequence extends Thread
{
private Object lock, unlock;
ThreadsInSequence(Object lock, Object unlock)
{
this.lock = lock;
this.unlock = unlock;
}
public void run()
{
synchronized(lock)
{
for(int i = 0; i < strs; ++i)
{
waiter();
if(array[0] == this)
{
System.out.println(i+1);
}
System.out.print(getName() + ' ');
++count;
if(array[thrs-1] == this)
{
System.out.println();
}
if(unlock != lock)
{
synchronized(unlock)
{
unlock.notify();
}
}
}
}
}
void waiter()
{
try
{
lock.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
System.exit(1);
}
}
public static Thread array[];
public static Object locks[];
public static int count, strs, thrs;
public static void main(String args[])
{
thrs = 3;
strs = 6;
count = 0;
locks = new Object[thrs];
array = new Thread[thrs];
for(int i = 0; i < thrs; ++i)
{
locks[i] = new Object();
}
for(int i = 0; i < thrs; ++i)
{
if(i != thrs-1)
{
array[i] = new ThreadsInSequence(locks[i],locks[i+1]);
}else
{
array[i] = new ThreadsInSequence(locks[i],locks[0]);
}
array[i].start();
}
synchronized(locks[0]) {
locks[0].notify();
}
}
}