如何确保特定线程首先完成执行而另一个最后执行?

时间:2014-08-17 06:19:53

标签: java multithreading concurrency

所以说主线程产生了3个线程(t1,t2,t3)。我如何确保特定线程首先完成执行,另一个线程最后完成。我并不是指在另一个“完成”后开始一个帖子,但是要确保他们按特定顺序完成

示例代码非常有用。

更准确地说,在游戏应用程序中,您可能希望首先更改图形,然后您希望生成声音,然后更新分数。

3 个答案:

答案 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结束时放置这样的等待没有多大意义,因为线程的完成顺序毫无意义。您必须在之前将放在依赖操作的开头。