0

I have written some Java code, which will call a C interrupt handler. In Java thread A, I use waitFor() to wait the interrupt coming and then execute reboot. In Java thread B, I will loop printing a counter value and sleep several milliseconds. And I hope when I detect the interrupt, and then stop the printing in thread B at once, but failed. In fact, the system detects the interrupt in time, but the printing continues for maybe 10 seconds and then reboot. Note: reboot occurs maybe 11 seconds after the interrupt(press a button), the hardware is not fast.

Below is my code, any suggestion? Thanks!

import java.io.IOException;

class ThreadTesterA implements Runnable
{
    private int counter;
    private String cmds[] = new String[1];
    private Process pcs;

    @Override
    public void run()
    {
        cmds[0] = "./gpio-interrupt";

        try {
            pcs = Runtime.getRuntime().exec(cmds);
            if(pcs.waitFor() != 0) {
                System.out.println("error");
            } else {
                ThreadTesterB.setClosed(true);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class ThreadTesterB implements Runnable
{
    private int i;
    private static boolean closed=false;

    public static void setClosed(boolean closed)
    {
        closed = closed;
    }

    @Override
    public void run()
    {
        // replace it with what you need to do
        while (!closed) {
            System.out.println("i = " + i);
            i++;
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println();
    }
}

public class ThreadTester
{
    public static void main(String[] args) throws InterruptedException
    {
        Thread t1 = new Thread(new ThreadTesterA());
        Thread t2 = new Thread(new ThreadTesterB());
        t1.start();
        t1.setPriority(Thread.MAX_PRIORITY);
        //t1.join(); // wait t1 to be finished
        t2.start();
        //t2.join();
    }
}
Tom Xue
  • 3,169
  • 7
  • 40
  • 77
  • Check this out http://stackoverflow.com/questions/2170520/inter-thread-communication-in-java – Nabin Aug 12 '14 at 16:17

1 Answers1

3

You're writing and reading a boolean variable (closed) from 2 different threads without any kind of synchronization. There is thus no guarantee that what you wrote in one thread is visible in the other thread. You need to either

  • make the boolean variable volatile
  • access the boolean variable (writing and reading) using blocks or methods synchronized on the same lock
  • use an AtomicBoolean instead of a boolean

I would use the third solution.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    Indeed, the reads and writes must be made thread safe. However, at the moment `ThreadTesterB.closed` is never changed at all as the statement `closed = closed;` has no effect. Naming a parameter the same as a `static` variable has some drawbacks, especially when not using an IDE which gives a warning in such cases… – Holger Aug 13 '14 at 13:54