Java 线程和同步

Java 线程和同步,java,multithreading,parallel-processing,synchronization,Java,Multithreading,Parallel Processing,Synchronization,我建立了一个GTA程序,当玩家使用资源时,其他人不能使用它 我试图改变优先顺序,但这似乎没有帮助。 你可以看到,在player4开始使用枪支后,player3也开始使用枪支,他不应该这样做。 我想做的是,当玩家使用一个对象时,在玩家完成之前,其他人都不能访问它。 提前谢谢 资源: package GTA; public class Resources { static final Object guns = "guns"; static final Objec

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

资源:

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!
玩家:

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!
输出:

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!
你可以看到,在player4开始使用枪之后,player3和他 不应该

如果线程已经在同步块中,则同步块不会告诉线程跳过该块。它只是告诉线程等待另一个线程完成。因此,在您的代码中,所有线程都将执行受
synchronized
保护的所有这三个块,而不管线程在该块中停留多长时间
sleep(2000)尽管这些块的执行将按顺序执行

如果要限制可以访问某个资源(例如,执行一段代码)的线程数,则需要使用(或类似)线程

我想做的是当一个玩家使用一个物体时 其他人应该能够访问它,直到玩家完成

如果你所说的对象分别是指
毒品
。然后,您将实现不会有多个播放器(即线程)同时使用这些对象


如果“玩家完成后”指的是整个运行,则需要使用单个锁同步
run()
方法的整个块。

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

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!");
        }
    }
}

}

我想以下是您想要的。如果要限制线程在使用资源时以同步方式运行,则应同步对资源的访问:

资源类别:

示例仅适用于枪支:

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!");
}
}

您实际上并没有问任何问题。当线程处理完资源时,您应该添加输出,以使输出更易于解释。现在,只有知道不同消息弹出的时间,我们才能判断输出是否“有问题”。@dreamcrash:有吗?回答关于多线程的问题已经够难了。此外,不得不猜测这个问题意味着很快就不值得投入精力了。