Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
120 views
in Technique[技术] by (71.8m points)

java - Threads and sync

I build a GTA program that when player is using resource no one else can use it I tried to change priorities but this didn't seems to help. you can see that after player4 started using guns also player3 and he shouldn't. what I am trying to do is that when a player using an object no one else should be able to access it until the player finished. thanks in advance!

Resources:

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();
    }
}

Player:

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

Output:

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!

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

you can see that after player4 started using guns also player3 and he shouldn't.

The synchronization block will not tell threads to skip that block if a threads is already inside. It just tells the thread to wait until the other thread is finished. Therefore, in your code all threads will execute all the those three blocks protected by the synchronized, regardless of how long the thread stay inside that block sleep(2000); albeit the execution of those blocks will be performed sequentially.

If you want to limit the number of threads that can access a certain resource (e.g., execute a block of code) you need to use Semaphore (or alike) for that purpose.

what I am trying to do is that when a player using an object no one else should be able to access it until the player finished.

If by object you mean separately the guns, drugs, money. Then you achieve that there will not be multiple player (i.e., threads) using those objects simultaneously.

If by "after the player have finish" you mean the entire run then you need to synchronize the entire block of the run() method using a single lock.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...