【问题标题】:How to stop the printing in thread A from thread B?如何从线程 B 停止线程 A 中的打印?
【发布时间】:2014-08-12 16:06:56
【问题描述】:

我编写了一些 Java 代码,它们将调用 C 中断处理程序。 在 Java 线程 A 中,我使用waitFor() 等待中断到来,然后执行重启。 在 Java 线程 B 中,我将循环打印一个计数器值并休眠几毫秒。 我希望当我检测到中断时,然后立即停止线程 B 中的打印,但失败了。事实上,系统会及时检测到中断,但打印可能会持续 10 秒,然后重新启动。 注意:可能会在中断(按下按钮)后 11 秒重新启动,硬件并不快。

下面是我的代码,有什么建议吗?谢谢!

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();
    }
}

【问题讨论】:

标签: java multithreading


【解决方案1】:

您正在从 2 个不同的线程中写入和读取布尔变量 (closed),而没有任何同步。因此,无法保证您在一个线程中编写的内容在另一个线程中可见。您需要

  • 使布尔变量可变
  • 使用在同一锁上同步的块或方法访问布尔变量(写入和读取)
  • 使用 AtomicBoolean 代替布尔值

我会使用第三种解决方案。

【讨论】:

  • 确实,读写必须是线程安全的。但是,目前 ThreadTesterB.closed 根本没有改变,因为声明 closed = closed; 无效。将参数命名为与static 变量相同的名称有一些缺点,尤其是在不使用在这种情况下会发出警告的 IDE 时……
猜你喜欢
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 2013-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多