线程和同步

yeotifhr  于 2021-06-27  发布在  Java
关注(0)|答案(3)|浏览(284)

我建立了一个gta程序,当玩家使用资源时,其他人不能使用它,我试图改变优先级,但这似乎没有帮助。你可以看到,在玩家4开始使用枪支后,玩家3也开始使用枪支,而他不应该使用。我想做的是,当玩家使用一个对象时,在玩家完成之前,其他人不应该能够访问它。提前谢谢!
资源:

package GTA;
public class Resources
{
    static final Object guns = "guns";
    static final Object drugs = "drugs";
    static final Object money = "money";

    public static void main(String[] args) 
    {
        Player[] p = new Player[4];
        p[0] = new Player("player1");
        p[1] = new Player("player2");
        p[2] = new Player("player3");
        p[3] = new Player("player4");
        p[0].start();
        p[1].start();
        p[2].start();
        p[3].start();
    }
}

玩家:

package GTA;
public class Player extends Thread
{
    public Player(String name) {super(name);}
    public void run()
    {
        synchronized (Resources.guns)
        {
            System.out.println(getName() + " is using the guns");
            setPriority(7);

            try {   sleep(2000);}
            catch(InterruptedException e) {e.printStackTrace();}
        }

        synchronized (Resources.drugs)
        {
            System.out.println(getName() + " does some drugs");
            setPriority(4);

            try {   sleep(2000);}
            catch(InterruptedException e) {e.printStackTrace();}
        }

        synchronized (Resources.money)
        {
            System.out.println(getName() + " is swimming in money right now");
            setPriority(1);

            try {   sleep(2000);}
            catch(InterruptedException e) {e.printStackTrace();}
        }
        System.out.println(getName() + " Wasted!");
    }
}

输出:

player1 is using the guns
player1 does some drugs
player4 is using the guns
player3 is using the guns
player4 does some drugs
player1 is swimming in money right now
player3 does some drugs
player4 is swimming in money right now
player1 Wasted!
player2 is using the guns
player4 Wasted!
player2 does some drugs
player3 is swimming in money right now
player2 is swimming in money right now
player3 Wasted!
player2 Wasted!
w8biq8rn

w8biq8rn1#

我想以下就是你要找的。如果要限制线程在使用资源时以同步方式运行,则应同步对资源的访问:
资源类别:
示例仅适用于枪:

class Resources {
static synchronized void useGun(String playerName) {
    System.out.println(playerName + "is using the gun");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    Player[] p = new Player[4];
    p[0] = new Player("player1");
    p[1] = new Player("player2");
    p[2] = new Player("player3");
    p[3] = new Player("player4");
    p[0].start();
    p[1].start();
    p[2].start();
    p[3].start();
}
}

玩家等级:

class Player extends Thread {

private String name;

public Player(String name) {
    super(name);
    this.name = name;
}

public void run() {
    Resources.useGun(name);
    System.out.println(getName() + " Wasted!");
}
}
scyqe7ek

scyqe7ek2#

你可以看到,在玩家4开始使用枪支后,玩家3也开始使用枪支,而他不应该使用。
如果线程已经在同步块中,同步块不会告诉线程跳过该块。它只是告诉线程等待另一个线程完成。因此,在您的代码中,所有线程都将执行受 synchronized ,不管线程在该块中停留多长时间 sleep(2000); 尽管这些块的执行将按顺序进行。
如果要限制可以访问某个资源(例如,执行一段代码)的线程数,则需要使用信号量(或类似的方法)。
我想做的是,当玩家使用一个对象时,在玩家完成之前,其他人不应该能够访问它。
如果你所说的物体是指 guns , drugs , money . 这样就不会有多个播放器(即线程)同时使用这些对象。
如果“玩家完成后”是指整个跑步,那么你需要同步整个跑步记录块 run() 方法使用单个锁。

busg9geu

busg9geu3#

三个监视器由三个对象组成,每个对象都有一个独立的锁。您应该使用一个对象资源监视器来获取锁。你可以试试:

public class Solution01 {

static final Object guns = "guns";

public static void main(String[] args) {
    Player[] p = new Player[4];
    p[0] = new Player("player1");
    p[1] = new Player("player2");
    p[2] = new Player("player3");
    p[3] = new Player("player4");
    p[1].setPriority(3);
    p[2].setPriority(2);
    p[3].setPriority(1);
    p[0].start();
    p[1].start();
    p[2].start();
    p[3].start();
}

public static class Player extends Thread {

    public Player(String name) {
        super(name);
    }

    public void run() {
        synchronized (Solution01.guns) {
            System.out.println(getName() + " is using the guns");
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(getName() + " does some drugs");
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(getName() + " is swimming in money right now");
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(getName() + " Wasted!");
        }
    }
}

}

相关问题