首页 > 解决方案 > 奇怪的问题多线程Java。一些线程自己关闭?

问题描述

我在一个简单的程序中遇到了问题,该程序模拟了 N 个随机玩家的轮盘赌游戏。该程序工作 2-3 次而不是意外停止,因为我认为,一个线程处于等待状态或类似情况。我知道代码不是很好(比如我的英语),但这是我的第一次尝试。任何建议都非常感谢。抱歉,如果代码不是很干净,我真的找不到其他方法来执行此程序。

public class RouletteMultipla implements Runnable {
private int a;
private int ng; //number of player

public RouletteMultipla(int f) {
    ng = f;
}

int numero = 0;

public void ingioco() {
    a++; //How many player have put money
}

public void morto() {
    System.out.println("One player is died"); //Run out of Money
    ng--;
}

public void run() {
    while (true) {
        synchronized (this) {
            if (a == ng) { //until all player have put money
                numero = (new Numero().num); //Random from 0 to 36
                System.out.println("E' USCITO " + numero + "\n ");
                a = 0;
                for (double j = 0; j < 10000000; j = j + 0.1);
                notifyAll();
            }

        }

    }

}

public static void main(String[] args) {
    int ng = (int) (Math.random() * 14) + 1;
    RouletteMultipla r = new RouletteMultipla(ng);
    Thread roulette = new Thread(r);


    for (int i = 0; i < ng; i++) {
        Giocatore g = new Giocatore(i, r, ng); //create n player
        g.start();

    }
    roulette.start(); //create one roulette
    roulette.setPriority(10);

}

这是类播放器

public class Giocatore extends Thread {

private int id; //id of player
private int ng; //number of player

int soldi = 100; //money at start
int numero; //number
int puntata = 1; //roulette play at start

Giocatore(int i, RouletteMultipla s, int b) {
    id = i;
    r = s;
    ng = b;
}

RouletteMultipla r = new RouletteMultipla(ng);

public void run() {

    while (soldi > 0) {
        numero = ((int) (Math.random() * 35)) + 1;
        puntata = (int) (Math.random() * (soldi - 1)) + 1;
        soldi = soldi - puntata;
        System.out.println("ID:" + id + " Puntata:" + puntata + " Numero:" + numero + " SOLDI:" + soldi);

        r.ingioco(); //Increase "a variable"
        try {
            synchronized (r) {
                r.wait();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (numero == r.numero) {
            soldi = soldi + puntata * 36;
            System.out.println("Giocatore " + id + " HA VINTOOOOOOOOOO");
        }

    }
    r.morto(); // when money=0
}

}

标签: javamultithreading

解决方案


可能还有其他问题,但对我来说突出的一个问题是对ng变量的访问不是同步的,也不是原子的:

public void morto() {
    System.out.println("One player is died"); //Run out of Money
    ng--;
}

如果多个(玩家)线程同时调用此方法,则无法保证ng--实际导致ng包含正确数量的玩家。

理解问题的最简单方法可能是认为n--;n = n - 1;. 现在,如果两个线程同时运行它,它们可能都读取n为相同的值(例如 10),并且都存储相同的递减结果(例如 9)。尽管两个线程已经完成,但计数比应有的高一个。

您可能应该将该方法声明为synchronized. 我认为该方法存在类似的问题ingioco


推荐阅读