我有多个线程,都是从一个对象运行的。 我希望“主线程”单独运行直到某个点,然后它等待,所有其他线程一起运行,然后主线程唤醒等等..... 我在同步我的线程时遇到问题。我要么得到一个非法的监视器状态异常,要么陷入其中一个“等待”循环,这个循环假设接收一个永远不会到来的“通知”。
更具体地说,我有一个带数组的对象。数组中的每个单元都有一个线程,用于检查相邻的单元格,然后使用该信息更改其单元格。 为了使变化有序,我希望所有单元格首先检查它们的相邻单元格并保持它们产生的值,然后等待。 当所有这些都完成后,主线程将唤醒所有这些线程并且它们将更新它们各自的单元格。
我查找了“等待”和“通知”工作的方式,但我仍然不明白他们如何同步。从我的理解我需要将它们全部连接到一个对象,然后该对象是“锁定”,所以如果我在其方法上使用“同步”只有一个线程可以一次接近它?我怎样才能确保“等待”方法总是有“通知”来结束它?
编辑: 该方法基本上运行了康威的生命游戏。 代码的主要方向是这样的: LifeMatrix类扩展了JPanel。它有一系列面板,每个都是“死或活”(真/假)。 RunMatrixThread类扩展了线程,是协调代码的“主线程”。 CellThead类扩展了线程,并为矩阵中的每个单元格创建了CellThread。 所以我的想法是给所有线程“LifeMatrix”作为观察者,但如果我尝试通知LifeMatrix对象(使用matrix.notify())它给我Illigal Monitor状态异常,如果我尝试使用“通知所有“它被卡在RunMatrixThread的wait()命令中。 另外,我是否通知对象?或者我是否通知正在等待的线程?
答案 0 :(得分:0)
不要使用并行化。在使用线程之前,请考虑您是否真的可以并行化您的作业,因为如果您的所有任务必须彼此同步,则使用线程将无法在执行时间方面提供更好的性能。假设您有一个对象数组[a,b]如果必须等待b上的某些更改,则不能单独处理a和b,因此无法并行化您的工作。相反,如果你需要处理a,b和数组的所有元素,并在最后对它们执行一些计算,你可以使用join()方法加入线程。当您调用join方法时,您基本上将线程分支连接在一个(主线程)中。一个新线程将分叉你的主线程,join将加入这些线程。
答案 1 :(得分:0)
如果您正试图获得"工作线程"做一个由主管"授权/发起/发出的工作包裹。线程,然后您可能应该使用线程池(例如,https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html)
线程池负责创建工作线程和"同步"它们与主线程的活动,让您专注于工作人员执行的任务(或任务)。
数组中的每个单元格都有一个线程......
对于Conway的生活来说,方式太多的工作线程。如果工作纯粹是计算限制的,那么拥有比主机有处理器更多的线程没有意义。
如果我正在为具有N个处理器的主机编码生命,我将使用具有N个线程的线程池。并且,在每一代中,我都会让主线程将N个任务提交到池中:每个任务都会执行一个水平条纹板。
答案 2 :(得分:0)
好的,首先我要感谢你们所有人的帮助,你们给我的一些链接非常有帮助。
我发现了我的问题:我试图在同一个对象上同时使用来自2种不同类型线程的wait / notify方法。我有' CellThread'使用了wait和' notifyAll',我得到了' RunMatrixThread'这样做了。他们当然已经"同步"方法,但因为它们是两种不同类型的线程,这两种类型并不与EACH OTHER同步。 解决问题的是我在“RunMatrixThread”中制作了两个新的同步方法。 class,一个用于等待,一个用于通知,然后只要我想等待/通知就从所有线程(来自两个线程类)调用这些方法。通过这种方式,有一个统一的对象可以锁定所有内容。
PS:我知道使用这么多线程是个坏主意。这是粗略的任务,他们要求我们这样做。