Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确保两个线程在一个循环中一个接一个-Android_Java_Android_Multithreading - Fatal编程技术网

Java 确保两个线程在一个循环中一个接一个-Android

Java 确保两个线程在一个循环中一个接一个-Android,java,android,multithreading,Java,Android,Multithreading,我有两条这样开始的线 Thread player1Thread = new Thread(new Player1RunnableManual()); player1Thread.start(); Thread player2Thread = new Thread(new Player2RunnableManual()); player2Thread.start(); 两个玩家,玩家1和玩家2,以不同的方式一次猜100个数字。我们可以忽略他们用来猜测数字的启发式方

我有两条这样开始的线

    Thread player1Thread = new Thread(new Player1RunnableManual());
    player1Thread.start();
    Thread player2Thread = new Thread(new Player2RunnableManual());
    player2Thread.start();
两个玩家,玩家1和玩家2,以不同的方式一次猜100个数字。我们可以忽略他们用来猜测数字的启发式方法。 我需要确保player1先运行,然后player2运行他们player1运行,然后player2再次运行,直到其中一人猜到一个特定的数字(硬编码)

我尝试使用可重入锁,但无法使其工作。player1和player2的可运行项如下所示

如何编写锁实现以使其工作

class Player1RunnableManual implements Runnable {
    @Override
    public void run() {
        while (!gopherFound) {
            r = new Random();
            final int player1Position = r.nextInt(high - low) + low;
            final int outcome = calculateProximity(player1, player1Position);
            if (outcome != DISASTER) {
                runnableHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (holes[player1Position] == 0) {
                            setPosition(player1, player1Position);
                            player1Status.setText(outcomesList[outcome]);
                        }
                    }
                });
                if (outcome == SUCCESS) {
                    gopherFound = true;
                    winner = "Player 1";
                    result.setText("Player 1 wins");
                    break;
                }
            }
            try {
                int sleep = r.nextInt(threadHigh - threadLow) + threadLow;
                Thread.sleep(sleep);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
        }
    }
}


class Player2RunnableManual implements Runnable {

    @Override
    public void run() {
        for (int i = 1; i <= 100 && !gopherFound; i++) {
            final int player2Position = i;
            final int outcome = calculateProximity(player2, player2Position);
            if (outcome != DISASTER) {
                Message msg = messageHandler.obtainMessage(player2);
                msg.arg1 = player2Position;
                msg.arg2 = outcome;
                messageHandler.sendMessage(msg);
                if (outcome == SUCCESS) {
                    gopherFound = true;
                    winner = "Player 2";
                    result.setText("Player 2 wins");
                    break;
                }
            }
            try {
                int sleep = r.nextInt(threadHigh - threadLow) + threadLow;
                Thread.sleep(sleep);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
        }
    }
}
class Player1RunNameManual实现可运行{
@凌驾
公开募捐{
而(!gopherFound){
r=新随机数();
最终整数播放器1位置=r.nextInt(高-低)+低;
最终int结果=计算概率(玩家1,玩家1位置);
如果(结果!=灾难){
runnableHandler.post(新的Runnable(){
@凌驾
公开募捐{
if(孔[Player1位置]==0){
设置位置(播放器1、播放器1位置);
player1Status.setText(结果列表[结果]);
}
}
});
如果(结果==成功){
gopherFound=true;
获胜者=“玩家1”;
result.setText(“玩家1获胜”);
打破
}
}
试一试{
int sleep=r.nextInt(threadHigh-threadLow)+threadLow;
睡眠;
}捕获(例外e){
e、 printStackTrace();
}最后{
}
}
}
}
类player2runnamanual实现可运行{
@凌驾
公开募捐{

对于(int i=1;i为什么不使用单线程执行器?可运行程序将排队

Executor executor = Executors.newSingleThreadExecutor();
while(!gopherFound){
    executor.execute(new Player1RunnableManual());
    executor.execute(new Player2RunnableManual());
    // wait here for the end of the 2 runnables, maybe using Future tasks instead of runnables
}
您可以清理代码,可运行程序内部不能再有“while(!gopherFound)”,但是有了这个,您可以确保可运行程序一个接一个地执行


另一种方法是使用“信号量(1)”,也将使用“获取()”和“释放()”来完成任务方法,但它不能保证先执行哪个线程。

要使
player1Thread
player2Thread
之前开始执行
player1Thread
您需要在
player1Thread
上调用
join
,然后再启动
player2Thread
。但这意味着
player2Thread
将不会启动,除非
player2Thread
死亡。
解决方法是,如果您知道
player1Thread
启动多长时间后,是否应该
player2Thread
启动,然后将该持续时间(转换为毫秒)作为参数传递给
player1Thread

使用单个线程
Executor
并按顺序提交
player1runnamanual
player2runnamanual
。此外,不要忘记关闭
Executor


关于您使用
可重入锁
的方法
可重入锁
是使用
同步
块的面向对象等价物。您可以通过将一个块转换为另一个块来进行一些练习。它只执行同步,不保证线程执行顺序。访问共享对象将是决定性的由线程调度程序执行,它有点随机。

以确保一个操作将一个接一个地启动。您可以简单地使用
ThreadPoolExecutor
。就像下一步一样

final ThreadPoolExecutor executor = 
  (ThreadPoolExecutor) Executors.newFixedThreadPool(1);

executor.submit(new Runnable() {
     @Override 
     public void run() { 
           // Your action 1
     }
});

executor.submit(new Runnable() {
     @Override 
     public void run() { 
           // Your action 2
     }
})