当前位置: 首页 > 知识库问答 >
问题:

如何同步使用多个线程?

裴兴言
2023-03-14

我有多个线程,它们都从一个对象运行。我希望“主线程”单独运行,直到某一点,然后它等待,所有其他线程一起运行,然后主线程唤醒,等等。。。。。我无法同步线程。我要么得到一个非法的监视器状态异常,要么它卡在一个“等待”循环中,该循环应该接收一个永远不会到达的“通知”。

更具体地说,我有一个带有数组的对象。阵列中的每个单元都有一个线程,该线程检查相邻单元,然后使用该信息更改其单元。为了有序地进行更改,我希望所有单元格首先检查相邻单元格并保留生成的值,然后等待。当所有这些操作完成后,主线程将唤醒所有这些操作,并更新各自的单元格。

我查看了“等待”和“通知”是如何工作的,但我仍然不明白它们是如何同步的。据我所知,我需要将它们全部连接到一个对象,然后该对象就是“锁”,所以如果我在其方法上使用“同步”,一次只能有一个线程接近它?如何确保“wait”方法始终有一个“notify”来结束它?

编辑:该方法基本上运行康威的生活游戏。代码的主要方向是这样的:类LifeMatrix扩展了JPanel。它有一系列面板,每个面板要么是“死的”,要么是“活的”(真/假)。RunMatrixThread类扩展了thread,是协调代码的“主线程”。CellThead类扩展了thread,并为矩阵中的每个单元格创建了CellThread。因此,我的想法是将“LifeMatrix”作为观察者提供给所有线程,但如果我尝试通知LifeMatrix对象(使用matrix.notify()),它会给我非法监视器状态异常,如果我尝试使用“notify all”,它会卡在RunMatrixThread的wait()命令中。还有,我要通知一个对象吗?还是通知正在等待的线程?

共有3个答案

邵弘伟
2023-03-14

好的,首先我想感谢你们所有人的帮助,你们给我的一些链接非常有用。

我发现了问题所在:我试图在同一个对象上同时使用来自两种不同类型线程的wait/notify方法。我的“CellThread”使用wait和“notifyAll”,我的“RunMatrixThread”也使用同样的方法。它们当然有“同步”方法,但因为它们是两种不同类型的线程,所以这两种类型彼此不同步。解决这个问题的方法是,我在“RunMatrixThread”类中创建了两个新的同步方法,一个用于等待,一个用于通知,然后只要我想等待/通知,就从所有线程(两个线程类)调用这些方法。这样,就有了一个统一的对象,它锁定了所有的东西。

PS:我知道使用这么多线程是个坏主意。这是粗人的任务,他们要求我们这样做。

酆耀
2023-03-14

如果您试图让“工作线程”完成由“主”线程授权/发起/分发的工作包,那么您可能应该使用线程池(例如,https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html)

线程池负责创建工作线程,并将它们的活动与主线程“同步”,它允许您专注于工作线程执行的任务。

数组中的每个单元格都有一个线程。。。

对于康威来说,这是太多的工作线程了。如果这项工作纯粹是受计算限制的,那么没有必要让更多的线程超过主机的处理器来执行它们。

如果我为一个有N个处理器的主机编写life,我会使用一个有N个线程的线程池。而且,在每一代中,我都会让主线程向池中提交N个任务:每个任务都会执行一个水平条带。

巫马修为
2023-03-14

不要使用并行化。在使用线程之前,请考虑是否真的可以并行化作业,因为如果所有任务都必须彼此同步,那么使用线程不会在执行时间方面给您带来更好的性能。假设你有一个对象数组[a,b],如果a必须等待b上的一些更改,你不能单独处理a和b,所以你不能并行化你的作业。相反,如果需要处理a、b和数组中的所有元素,并在最后对它们执行一些计算,则可以使用Join()方法连接线程。当调用join方法时,基本上是将线程分支连接到一个(主线程)中。一个新线程将分叉你的主线程,join将连接这些线程。

 类似资料:
  • 我已经面临这个问题很多天了,请帮我解决。我正在使用线程同步实现生产者-消费者示例。我在这个传统节目中做了一些调整。我没有只使用一个队列对象,而是使用了两个队列对象。但程序不起作用。。(PS-我知道我可以通过只使用队列的一个对象来让这个程序工作,但如果我想使用两个队列对象呢??) 类队列{ } 类生产者实现Runnable{ } 类消费者实现可运行{ } 公共类测试队列{ }

  • 问题内容: 在面试中被问到这个问题,试图解决…但是没有成功。我想到了使用CyclicBarrier 有三个线程T1打印1,4,7 … T2打印2,5,8 …,T3打印3,6,9…。您如何同步这三个来打印序列1,2,3,4,5,6,7,8,9…。 我尝试编写并运行以下代码 输出 谁能帮助我纠正错误? 类似的 线程同步查询-同步三个线程以打印012012012012.....无法正常工作 问题答案:

  • 在采访中被问到这个问题,试图解决它。。。但并不成功。我想用自行车旅行车 有三个线程T1打印1,4,7... T2打印2,5,8......和T3打印3,6,9......你如何将这三个同步到打印序列1,2,3,4,5,6,7,8,9...... 我试着写作 输出 有人能帮我纠正错误吗? 类似的Ques线程同步-将三个线程同步到打印012。。。。。不起作用

  • 问题内容: 我需要使用单个任务队列和单个结果队列来启动许多工作程序。每个工人都应该以不同的goroutine开始。我需要等到所有工作人员都将完成并且任务队列将为空后再退出程序。我已经准备了goroutine同步的小例子。主要思想是我们将排队的任务计数,并等待所有工人完成工作。但是当前的实现有时会遗漏值。为什么会发生这种情况以及如何解决问题?示例代码: 问题答案: 使用sync.WaitGroup等

  • 线程2:4 . . 线程3:7 线程3:8 线程1:9 这是我为正在执行线程的类编写的代码 我认为问题在于NumberEntry对象的创建。但我不太确定怎么修好它。如果有人能以任何方式帮助我,那就太好了:)。

  • 当我尝试通过启动不同的线程来执行所有同步方法时,我在一个类中有三个同步方法,我看不到同步的输出,在对象上没有获得锁 公共类DisplayMessage{ }线程类: 公共类 MyThread 扩展了线程 { }Thread2类:公共类MyThread2扩展线程{ } 线程 3 类: 包装Synchronization.classlock; 公共类MyThread3扩展线程{ } 使用main方法生