0

It does not create nor launch more than one thread.

I tried to make the poller class to implement runnable and invoke it with run(). Also made it extend from thread and invoke it with start(). I added System.out.println(i) within the caller function pollRows() and it just prints "1".

public void pollRows() throws InterruptedException {
        for (int i = 1; i < 17; i++) {
            System.out.println(i);
            Poller rowPollerThread = new Poller(port, rows[i]);
            rowPollerThread.start();                             
        }
    }


public class Poller extends Thread {

private static byte[] pollerBytes = {
    (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x08, (byte) 0x45, (byte) 0xc9
};

private static byte[] polledBytes;

private static com.fazecast.jSerialComm.SerialPort serialPort;

private static Row row;

public Poller(com.fazecast.jSerialComm.SerialPort serialPort, Row row) {
    this.serialPort = serialPort;
    this.row = row;
}

@Override
public void start() {
    try {
        while (true) {
            getHelioStates();
        }
    } catch (InterruptedException ex) {
        Logger.getLogger(Poller.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private static void getHelioStates() throws InterruptedException {
    for (int i = 0; i < row.getHeliostats().length; i++) {            
        writeFrame(i);
        readByteFrame();
        setHelioStates(row.getHeliostats()[i]);
        Thread.sleep(1000);
    }
}

private static void writeFrame(int i) {
    pollerBytes[0] = (byte) row.getAddresses()[i];
    serialPort.writeBytes(pollerBytes, 8);
}

private static void readByteFrame() {
    polledBytes = new byte[serialPort.bytesAvailable()];
    serialPort.readBytes(polledBytes, polledBytes.length);
}

private static void setHelioStates(Heliostat heliostat) {        
    for (int i = 0; i < polledBytes.length; i++) {            
        Byte b = polledBytes[i];
        heliostat.bytePosition(i, b);
    }
}

}

It only creates and launch the first thread, the output from the launched thread is as expected.

  • 4
    You need `start()` instead of `run()` to make new threads. But you say you tried that. So what happened? Any errors? How do you know that there are no extra threads? Can you add some `System.out.println()` for debugging before your infinite loop? What does `getHelioStates()` do? – Thilo Jul 15 '19 at 12:38
  • I guess it has something to do with the fact that the launched thread never finish since the run method contains a bucle while(true) – user11330490 Jul 15 '19 at 12:39
  • does getHelioStates block? in any case just add log in last line of for loop. you will see how many threads are started – Bartosz Bilicki Jul 15 '19 at 12:40
  • 5
    What is wrong with the [Executors](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html)? Are there any specific reason for reinventing the wheal ? – Victor Gubin Jul 15 '19 at 12:40
  • "I guess it has something to do with the fact that the launched thread never finish since the run method contains a bucle while(true)" no, it is because you never start/launch another thread. call `start()` not `run()` – matt Jul 15 '19 at 12:43
  • No erros when I used start() just the same behavior, I added a sout(i) with the iterator variable i and it only prints "1". getHelioStates() writes and read a serial port and apparently does it fine. – user11330490 Jul 15 '19 at 12:46
  • Did you also override `start()`? Because that's not good idea. Best to not `extends Thread` at all, just `implements Runnable`. – Thilo Jul 15 '19 at 12:50
  • If getHelioStates is synchronized then all of your threads can block on the one method. Can you update your code with what you're currently running, and explain the output? – matt Jul 15 '19 at 12:53
  • Does it work if you remove the call to `getHelioStates()` (replace it with print + sleep)? – Thilo Jul 15 '19 at 13:02
  • Your latest code still has `run()`. Please update and confirm that you did try `start()`. – Thilo Jul 15 '19 at 13:03
  • start will launch new call of stack, run() will execute in the current thread. – ppuskar Jul 15 '19 at 13:09

2 Answers2

2

Don't override start method of Poller class because start method causes thread to begin execution. You should override run method.

@Override
public void run() {
    try {
        while (true) {
            getHelioStates();
        }
    } catch (InterruptedException ex) {
        Logger.getLogger(Poller.class.getName()).log(Level.SEVERE, null, ex);
    }
}
redMist
  • 219
  • 2
  • 12
0

Your threads aren't working correctly because you haven't defined a run() method.

Javadoc for Thread (https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html) explains the two ways to create a new thread:

  • declare a class to be a subclass of Thread. This subclass should override the run method of class Thread.
  • create a thread is to declare a class that implements the Runnable interface. That class then implements the run method.

Both should be started by calling the start() method (which you were correctly doing), however both also require that you implement run() to define your thread's behavior (which is not in your code above).

It might help to add some printed output to your run() method, like this:

@Override
public void run() {
    System.out.println("thread " + this.getName() + " is now running");
    // do other things in thread
}

That will show you that all of your threads are created, and also shows that the sequence in which you call start() is not the same sequence in which run() is called.

Kaan
  • 5,434
  • 3
  • 19
  • 41