【问题标题】:Java Thread concept / demoJava 线程概念/演示
【发布时间】:2013-05-12 18:44:23
【问题描述】:

我正在尝试编写一个使用线程的 Java 程序。我希望能够在程序启动时运行 3 个线程,并让它们在“工作订单”的 ArrayList 上等待。 最初,不会有工单。所以线程应该等待。 在未来的某个时刻,工作指令会被添加到 ArrayList 中,主线程必须通知线程有工作要做。

我希望能够通过扩展 Thread(而不是实现 Runnable)来做到这一点。

我认为我遇到的主要问题是线程没有与工作订单 ArrayList 正确同步。

我的代码如下所示:

  public static void main(String[] args) {

    AnotherRunnable anotherRunnable = new AnotherRunnable();
    ArrayList<ATMRunnable> workOrders = new ArrayList<ATMRunnable>();

    T1 t1 = new T1(anotherRunnable, workOrders);
    T1 t2 = new T1(anotherRunnable, workOrders);

    t1.start();
    t2.start();

    try{
        Thread.sleep(2000);
    }
    catch(InterruptedException e){}

        synchronized (workOrders){

        System.out.println(t1.getState() + " - " + t1.getName());
        System.out.println(t2.getState() + " - " + t2.getName());

        System.out.println("notify");
        workOrders.notify();

        System.out.println(t1.getState() + " - " + t1.getName());
        System.out.println(t2.getState() + " - " + t2.getName());

    }
  }

AnotherRunnable 类:

public class AnotherRunnable implements Runnable {

public void run()
{
    System.out.println("AnotherRunnable");

}
}

还有 Tread 类:

公共类 T1 扩展线程 {

 AnotherRunnable anotherRunnable;
ArrayList<ATMRunnable> workOrders;

ATMThread(AnotherRunnable anotherRunnable, ArrayList<ATMRunnable> workOrders)
{
    this.anotherRunnable = anotherRunnable;
    this.workOrders = workOrders;
}

public void run()
{
    System.out.println("Run Thread");

    synchronized (workOrders){
        try{
            System.out.println("wait Thread");
            workOrders.wait();
        }
        catch (InterruptedException e){}
    }

}

}

这是程序的输出:

Run Thread
wait Thread
Run Thread
wait Thread
WAITING - Thread-1
WAITING - Thread-2
notify all
BLOCKED - Thread-1
WAITING - Thread-2

如您所见,在调用 workOrders 对象上的 notify 之后,第一个线程的状态更改为 Blocked。但是线程和可运行对象都没有被执行。

任何帮助将不胜感激。

【问题讨论】:

  • 有很多问题 - 其中之一是您从不致电 anotherRunnable.run(),因此您无法看到打印的 AnotherRunnable... 您也致电 notify,而不是notifyAll 所以只唤醒了一个线程。
  • @assylias 线程通过调用start() 方法启动。 run() 不应从程序员代码中调用。
  • @SJuan76 你没抓住重点。当你重写一个Thread的run方法时,它不会再调用传递给构造函数的Runnable了。
  • 忽略这里的其他问题,如果您只是使用LinkedBlockingDeque 而不是尝试使用ArrayList,一切都会变得相当容易
  • 如果您想控制多线程工作,请考虑查看执行程序而不是自己使用线程

标签: java multithreading thread-safety


【解决方案1】:

你应该在java中使用并发集合来尽可能避免手动同步。

我希望能够在程序启动时运行 3 个线程,并让它们在“工作订单”的 ArrayList 上等待。最初,不会有工单。所以线程应该等待。在未来的某个时刻,工作指令会被添加到 ArrayList 中,主线程必须通知线程有工作要做。

对于这种同步,Blocking queues 是像LinkedBlockingQueue 这样的朋友,当队列中没有项目或队列已满时,线程会等待。您不需要任何同步/等待/通知。

您也可以查看是否有帮助:synchronization is risky

如果只是为了学习目的,你必须首先在逻辑上使你的同步正确。它不使用任何有问题的等待或通知条件。如果合适,它会起作用,但不是首选方式。

【讨论】:

  • 谢谢。我希望能够在没有 LinkedBlockingQueue 的情况下手动完成。这只是一个理论练习。我需要了解为什么,在线程上运行没有被调用。是因为我在 ArrayList 上同步的方式吗?
【解决方案2】:

我发现我必须做些什么才能让它工作。主要是缺少的概念。我不得不循环运行线程的运行方法。我在想每次调用 notifyall 时都会调用该方法,这是不正确的。当对同步对象调用 wait() 时,线程停止,并通知它恢复执行,如果该代码不在循环中,则不会执行。

【讨论】:

    猜你喜欢
    • 2014-02-25
    • 2011-01-20
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多