简体   繁体   English

在Java中使用相同变量的线程

[英]Threads using the same variable in java

I'm working with threads and have a problem, because my threads are using the same variables created by other thread based on another class. 我正在使用线程并遇到问题,因为我的线程使用的是基于其他类的其他线程创建的相同变量。 The problem is with this code: 问题在于此代码:

public void run() {
    int cityID = 0;
    int requestID = 0;
    boolean inBase = true;
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    while (inBase == true) {
        for (cityID = 0; cityID < world.getCities().size(); cityID++) {
            if ((!world.getCities().get(cityID).getRequestsList().isEmpty()) && (inBase == true)) {
                for (requestID = 0; requestID < world.getCities().get(cityID).getRequestsList()
                        .size(); requestID++) {
                    if (world.getCities().get(cityID).getRequestsList().get(requestID).isRequest() == true) {
                        world.getCities().get(cityID).getRequestsList().get(requestID).setRequest(false);
                        System.out.println(Thread.currentThread().getName() + " is flying to "
                                + world.getCities().get(cityID).getName());
                        inBase = false;
                        break;
                    }
                }
            }
        }
    }
}

The result is: 结果是:

City 859|342 is sending request for airplane. . .
City 328|669 is sending request for airplane. . .
City 718|287 is sending request for airplane. . .
Airplane kS-2 is flying to City 859|342
Airplane kS-1 is flying to City 859|342

As you see Airplanes are flying to the same City and that's wrong. 如您所见,飞机正在飞往同一座城市,这是错误的。 Don't know what should I do to prevent this situation, because I have already done condition 不知道该怎么办才能防止这种情况,因为我已经做好了条件

if world.getCities().get(cityID).getRequestsList().get(requestID).isRequest() == true)

And then I change this value to false 然后我将此值更改为false

world.getCities().get(cityID).getRequestsList().get(requestID).setRequest(false);

But thread are looking for the same value in the same time, so all I can do is sleep each for random time then they won't check true value in the same time, but using random I can still get two the same values so Airplanes sometimes will fly to the same target. 但是线程在同一时间寻找相同的值,所以我所能做的就是随机睡眠每个时间,然后他们将不会在同一时间检查真实值,但是使用随机值我仍然可以获得两个相同的值,所以飞机有时会飞向同一目标。 I think there is a better way to do it but have no idea. 我认为有更好的方法可以做到,但一无所知。 Please help. 请帮忙。

The way i see is that all of your threads get access to the same request list at the same time so, instead of looping through 我看到的方式是,所有线程都可以同时访问同一请求列表,而不是循环遍历

world.getCities().get(cityID).getRequestsList()

have your list behave like a stack and pop the requests out one by one. 让您的列表表现得像一个堆栈,并一一弹出请求。 This way each pop will give your thread a separate request. 这样,每次弹出都会给您的线程一个单独的请求。

I cleaned up your code a little. 我整理了一下您的代码。 Its not entirely clear why you use threads in the first place. 尚不清楚为什么首先要使用线程。 You could very well just loop through your list in your main thread and create plane objects. 您可以在主线程中循环遍历列表并创建平面对象。 Those could be stored in a list for example. 例如,这些可以存储在列表中。 I assume you might want to use the threads to simulate the planes flying? 我假设您可能想使用线程来模拟飞行的飞机? If that is the case and the run method is not finished after the while(inBase) then you might want to use a lock object to make sure only one thread at a time can modify your world: 如果是这种情况,并且运行方法在while(inBase)之后仍未完成,那么您可能希望使用锁对象来确保一次仅一个线程可以修改您的世界:

//Define a lock object somewhere. Each thread must have access to this somehow.
private final Lock lock = new ReentrantLock();

public void run() {
    boolean inBase = true;
    //This thread is about to use and modify the world.
    //Wait for other threads to finish and occuppy the world by locking.
    lock.lock();
    while (inBase) {
        for (int cityID = 0; cityID < world.getCities().size() && inBase; cityID++) {
            City city = world.getCities().get(cityID);
            if (!city.getRequestsList().isEmpty()) {
                for (int requestID = 0; requestID < city.getRequestsList().size(); requestID++) {
                    Request request = city.getRequestsList().get(requestID);
                    if (request.isRequest()) {
                        request.setRequest(false);
                        System.out.println(Thread.currentThread().getName() + " is flying to " + city.getName());
                        inBase = false;
                        break;
                    }
                }
            }
        }
    }
    //This thread is finished with modifying the world.
    //Release the lock so other threads can use it.
    lock.unlock();
    //Do stuff that planes do while flying.
}

Some more infos about ReentrantLock: Java ist auch eine Insel - ReentrantLock 有关ReentrantLock的更多信息: Java ist eine Insel-ReentrantLock

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM