所以说主线程产生了3个线程(t1,t2,t3)。我如何确保特定线程首先完成执行,另一个线程最后完成。我并不是指在另一个“完成”后开始一个帖子,但是要确保他们按特定顺序完成。
示例代码非常有用。
更准确地说,在游戏应用程序中,您可能希望首先更改图形,然后您希望生成声音,然后更新分数。
答案 0 :(得分:0)
您可以使用wait()
和notify()
。它是一种机制,通过它我们可以在线程之间发送信号。
wait()
会导致线程在关键区域暂停。暂停时,线程释放锁定。必须在同步块或方法中调用它。
notify()
将向等待同一对象的其中一个线程发送信号。它唤醒调用notify()的线程。
以下是两个功能的示例:显示和声音。显示将在声音之前完成:
(你也可以添加第三个(得分)。)
class shared
{
synchronized void disp()
{
System.out.println("Display thread complete");
notify();
}
synchronized void play_s()
{
try
{
wait();
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
System.out.println("Sound thread complete");
}
}
class display extends Thread
{
shared sh;
public display(shared sh,String str)
{
super(str);
this.sh=sh;
start();
}
public void run()
{
sh.disp();
}
}
class sound extends Thread
{
shared sh;
public sound(shared sh,String str)
{
super(str);
this.sh=sh;
start();
}
public void run()
{
sh.play_s();
}
}
public class sync {
public static void main(String agrs[])
{
shared sh=new shared();
display d=new display(sh,"one");
sound s=new sound(sh,"two");
}
}
答案 1 :(得分:0)
“更准确地说,在游戏应用程序中,您可能希望先更改图形,然后您希望生成声音,然后更新分数。”
这需要顺序执行外部可见活动。图形更新必须在事件处理线程中进行,这似乎是对活动进行排序的明显位置。
我会为每个活动分离出任何计算密集型或其他耗时的准备工作,并将其委托给一个线程或线程池,而不必担心订单。使用例如invokeLater在计算完成后通知事件处理线程。在事件处理线程中,跟踪执行某些操作的条件,例如更改分数。如果满足所有条件,包括完成所有前提条件,请执行操作。
答案 2 :(得分:0)
您的问题没有多大意义,因为线程的完成对应用程序的状态没有影响,因此,完成顺序也完全不相关。你实际上想要达到的目标很可能需要一个不同的解决方案。
您的示例说明了这一点:“在游戏应用程序中,您可能希望首先更改图形,然后您希望生成声音,然后更新分数”。在这里,您将一个接一个地描述您希望执行的操作,这完全违背了您的声明“我并不是要在另一个”完成“之后开始一个线程。”
您可能意味着要加载或计算资源,例如图形和声音,同时但希望按顺序渲染它们。因此,关键是将加载/计算从渲染拆分为两个相关任务。然后,虽然图形渲染任务仅取决于图形创建的完成,但声音渲染依赖于声音数据创建和图形渲染的完成,以建立您期望的顺序。所以声音线程的完成并不取决于图形线程的完成,而是声音渲染的开始取决于图形渲染的完成。
有很多方法可以实现这些事情,但考虑到你的问题是多么抽象,它的范围太广了。
但是,关于您的原始问题,有Thread.join()
。当线程T2
执行的代码在线程T1
上调用该方法时,它将等待T1
的终止,因此线程T2
将不会在T1
之前终止}。但是,如上所述,在T2
结束时放置这样的等待没有多大意义,因为线程的完成顺序毫无意义。您必须在之前将放在依赖操作的开头。