简体   繁体   中英

Locking threads in java doesnt work

I have a simple problem with multithreading that I just cant figure out. I tried synchronizing methods and using locks but none of these worked so I hope someone here could help me.

public void startThreads(ArrayList<ArrayList<Tocka>> pLista) {
        ScheduledThreadPoolExecutor eventPool = new ScheduledThreadPoolExecutor(pLista.size());
            for(int i=0; i<pLista.size(); i++) {
                eventPool.execute(new Dretva(pLista.get(i),i));
            }
    }

public synchronized void run() {
        lock.lock();
        System.out.print(this.id + ". ");
        optimalnost.printOrder(this.lista);
        double distance = optimalnost.getDistanceList(this.lista);
        System.out.println(" - " + distance);
        System.out.println();
        checkMin(distance);
        lock.unlock();
    }

I call from test class startThreads method with List of lists(startThreads and thread are in separated classes). In class Dretva (thread), I have a run code which executes some calculations with list which is passed as argument and prints calculation. In my example there are 6 lists and I'm trying to pass all of them, but one at the time. When I don't use threads it works fine, but with threads like these i get messed up and shuffled output.

I need help how to make other threads wait while active thread isn't finished.

Here is screenshot of my problem:

在此处输入图片说明

The synchronized method is synchronized on that object, not globally.

Just pass in an object and synchronize on that:

public void startThreads(ArrayList<ArrayList<Tocka>> pLista) {
    final Object lockOb = new Object();

    ScheduledThreadPoolExecutor eventPool = new ScheduledThreadPoolExecutor(pLista.size());
        for(int i=0; i<pLista.size(); i++) {
            eventPool.execute(new Dretva(lockOb, pLista.get(i),i));
        }
}

Object lockOb;

public void run() {
    synchronized(lockOb) {
       System.out.print(this.id + ". ");
       optimalnost.printOrder(this.lista);
       double distance = optimalnost.getDistanceList(this.lista);
       System.out.println(" - " + distance);
       System.out.println();
       checkMin(distance);
    }
}       

Now all the objects are sharing one lock object and are all synchronizing on that, so only one will run at a time. This does entirely defeat the point of using threads though as you have created lots of threads, then deliberately made it so only one of those threads can execute at a time.

As a side note you should always use a try finally block for any sort of lock object that needs unlocking.

Your synchronized method run is a member method. This means that you are synchronizing on the instance of the object. Since you created multiple instances, each is obtaining a lock on a different object. If you desire to synchronize access across instances, you must either explicitly provide the mutex to lock on or utilize a static constant mutex for all instances to synchronize on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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