0

Yesterday found a wierd beahaviour while trying to implement daemon threads. If I am not using print() or calling synchronized() inside thread seems they don't start at all. Code of a problematic class is below, place with a "fix" is marked with "//////////":

package krio.thread;

import krio.buffer.GetNeighbours;
import krio.world.BufferedParticle;
import krio.world.CollisionSolver;
import krio.world.World;

import java.util.HashMap;
import java.util.List;

// wrapper for CollisionSolver
public class MyThread {
    public boolean startFlag;
    private Thread thread;

    // public ================================================
    public MyThread(HashMap<Integer, BufferedParticle> particles, GetNeighbours buffer, List<Integer> idSortedList) {
        thread = new Thread(() -> launch(particles, buffer, idSortedList));
        thread.start();
    }
    // private ===============================================
    private void launch(HashMap<Integer, BufferedParticle> particles, GetNeighbours buffer, List<Integer> idSortedList) {
        while (true) {
            ///////////////////////////////////////////////////////
            // idk why it is not working without this
            System.out.checkError();

            //System.out.print("+");                // or this

            //int a = 0;                            //
            //synchronized ((Object) a) { a = 0; }  // or this
            ///////////////////////////////////////////////////////

            if (startFlag) {
                CollisionSolver.solve(particles, buffer, idSortedList);
                startFlag = false;
            }
        }
    }
}

Calling it like:

package krio.thread;

import java.util.ArrayList;

public class MyPoolLauncher {
    private ArrayList<MyThread> pool;

    // public ================================================
    public MyPoolLauncher(ArrayList<MyThread> thrList) {
        pool = thrList;
    }

    public void launch() {
        for (MyThread thread : pool) thread.startFlag = true;
    }

    public boolean isReady() {
        boolean allReady = true;
        for (MyThread thread : pool) allReady = allReady && !thread.startFlag;
        return allReady;
    }
}

So the question: Can someone please explain why this happens and how to prevent those kind of situations in future? I assume I made dumb mistake somewhere, but I can't find it.

I am new to java and will appreciate any advice, thanks.

Solution:

use

public volatile boolean startFlag;
  • Where do you instantiate `MyThread`s? – akarnokd Jun 16 '22 at 11:14
  • 2
    `startFlag` should be volatile otherwise java is not obliged to read your `startFlag` field more than once. Synchronized code makes Java re-read your `startFlag`. Also `CollisionSolver.solve` might be crashing out the thread. – akarnokd Jun 16 '22 at 11:18

0 Answers0