Java 同一线程上的两个可运行程序同时结束。有可能发生冲突吗?

Java 同一线程上的两个可运行程序同时结束。有可能发生冲突吗?,java,android,callback,runnable,Java,Android,Callback,Runnable,下面是我对自定义视图的一些代码的简化。它有一个Runnable用于动画,一个Runnable用于音频。start()函数同时启动动画运行和音频运行。每个runnable在完成时实现一个带有回调的接口 我需要知道两者何时完成,这样我就可以在两个unnablesfinished()上调用 我已经用评论标记了几个感兴趣的领域。如果音频和动画可运行项同时完成,会发生什么情况?更具体地说,在上面的注释位置,一个可运行的回调是否会中断另一个可运行的回调?这可能吗 我希望不会,因为在两个unnablesfin

下面是我对自定义
视图的一些代码的简化。它有一个
Runnable
用于动画,一个
Runnable
用于音频。
start()
函数同时启动动画运行和音频运行。每个runnable在完成时实现一个带有回调的接口

我需要知道两者何时完成,这样我就可以在两个unnablesfinished()上调用

我已经用评论标记了几个感兴趣的领域。如果音频和动画可运行项同时完成,会发生什么情况?更具体地说,在上面的注释位置,一个可运行的回调是否会中断另一个可运行的回调?这可能吗


我希望不会,因为在两个unnablesfinished上的
将被调用两次。如果是这种情况,如何解决此问题?

您可以使用初始化为2的AtomicInteger

并以

if(atomicInt.decrementAndGet()==0)onBothRunnablesFinished();

可以使用初始化为2的AtomicInteger

并以

if(atomicInt.decrementAndGet()==0)onBothRunnablesFinished();

我会将一个POJO互斥对象注入两个可运行对象,并使用它同步
isRunning
onCompletion
方法。实际上,<代码> IsRuns不需要同步,因为它只是从代码中的同步代码中调用的。 使用RunnableA作为模板(对两个类进行标记为
//completion
的更改):


我会将一个POJO互斥对象注入两个可运行对象,并使用它同步
isRunning
onCompletion
方法。实际上,<代码> IsRuns不需要同步,因为它只是从代码中的同步代码中调用的。 使用RunnableA作为模板(对两个类进行标记为
//completion
的更改):


我已经删除了我的另一个答案。现在我想你甚至不需要Runnable,因为动画和媒体播放器框架将使用它们自己的线程。但是,您仍然需要同步对ActivityFinished()
(以前称为OnBothRunablesFinished())的调用,因为框架线程可能同时完成:

public class Foo extends View implements AnimationListener, OnCompletionListener {
    private MyAnimation mAnim;
    private MyMediaPlayer mMediaPlayer;
    private boolean mIsOneActivityFinished = false;

    synchronized private void onActivityFinished() {
        if(!mIsOneActivityFinished) {
             // The first activity is finished. Set the flag and return.
             mIsOneActivityFinished = true;
             return;
        }

        // Do stuff when both activities are finished...
    }

    public void start() {
        mAnim = new MyAnimation();
        mAnim.setAnimationListener(this);
        startAnimation(mAnim);

        mMediaPlayer = MyMediaPlayer();
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.start();
    }


    // Called when mAnim finishes
    @Override
    public void onAnimationEnd(Animation animation) {
        onActivityFinished();
    }


    // Called when mMediaPlayer finishes
    @Override
    public void onCompletion(MediaPlayer mp) {
        onActivityFinished();
    }
}
相信我,这个代码将工作,是干净的方式。甚至不要考虑使用Runnables,因为Android为您提供多线程


巴里

我删除了另一个答案。现在我想你甚至不需要Runnable,因为动画和媒体播放器框架将使用它们自己的线程。但是,您仍然需要同步对ActivityFinished()
(以前称为OnBothRunablesFinished())的调用,因为框架线程可能同时完成:

public class Foo extends View implements AnimationListener, OnCompletionListener {
    private MyAnimation mAnim;
    private MyMediaPlayer mMediaPlayer;
    private boolean mIsOneActivityFinished = false;

    synchronized private void onActivityFinished() {
        if(!mIsOneActivityFinished) {
             // The first activity is finished. Set the flag and return.
             mIsOneActivityFinished = true;
             return;
        }

        // Do stuff when both activities are finished...
    }

    public void start() {
        mAnim = new MyAnimation();
        mAnim.setAnimationListener(this);
        startAnimation(mAnim);

        mMediaPlayer = MyMediaPlayer();
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.start();
    }


    // Called when mAnim finishes
    @Override
    public void onAnimationEnd(Animation animation) {
        onActivityFinished();
    }


    // Called when mMediaPlayer finishes
    @Override
    public void onCompletion(MediaPlayer mp) {
        onActivityFinished();
    }
}
相信我,这个代码将工作,是干净的方式。甚至不要考虑使用Runnables,因为Android为您提供多线程



巴里

我很高兴你这么说。我想做一些类似的事情,但以前从未使用过原子原语,所以我犹豫了。不过,我确实有一个问题。根据android文档,这两个
可运行文件都在同一个线程上执行。在这种情况下,原子原语或同步函数仍然有效吗?这会使协调语义更加模糊。我们正在讨论如何同步可运行项,而忽略了全局。不必使用Runnable来启动这两个活动,因为它们的框架将使用自己的线程。因此,Foo可以充当这两个活动的侦听器,只需同步对onbothrunablesfinished()的调用。我想做一些类似的事情,但以前从未使用过原子原语,所以我犹豫了。不过,我确实有一个问题。根据android文档,这两个
可运行文件都在同一个线程上执行。在这种情况下,原子原语或同步函数仍然有效吗?这会使协调语义更加模糊。我们正在讨论如何同步可运行项,而忽略了全局。不必使用Runnable来启动这两个活动,因为它们的框架将使用自己的线程。因此,Foo可以充当这两个活动的侦听器,只需同步对onbothrunablesfinished()的调用。我将传递什么构造函数?新的
对象
视图
?另外,为什么我们不为
视图创建一个互斥对象呢?为每个
Runnable
创建互斥锁有什么好处?一个普通的对象,只要它对两个Runnable都是完全相同的实例。我不会使用视图实例,因为(依我看)将对象用作与其操作无关的状态的互斥体是非常糟糕的做法。是的,您可以将互斥体作为视图的一个成员,并从两个可运行文件中使用它-我只习惯于使用静态内部类和传递参数;我们的标准不鼓励使用内部类,因为这样很容易不小心弄乱包含类的状态。由于onAnimationEnd()和onCompletion()将由各自框架所拥有的线程调用,因此不需要使用可运行文件。多亏了软件Monkey和Barry Fruthman。这个讨论帮助我更好地理解了Java线程、Android API和我自己的代码?新的
对象
视图
?另外,为什么我们不为
视图创建一个互斥对象呢?为每个
Runnable
创建互斥锁有什么好处?一个简单的对象,只要