gpt4 book ai didi

java - 如何在父对象中同步(d)方法和修改对象的属性?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:29:38 26 4
gpt4 key购买 nike

我有两个从 Controller 类运行的线程。第一个线程接收 SMS 消息,只要程序处于启动状态,它就应该继续运行。另一个线程用于计算单元的 GPS 位置。

Controller 启动 SMS 线程并等待文本消息。如果文本消息满足特定条件,则会启动 GPS 定位线程并将坐标发送回 Controller 。

对于每个线程,我使用了以下格式:

reader = new Reader(this);
new Thread(reader).start();

读取器类然后使用 Controller 的引用,因此它可以调用 Controller 中的方法:

public void ReceivedCommand(String address) {
[..]
}

此方法然后创建一个 GPS 线程的实例,它本身从父对象(线程?)调用一个名为 ReceivedLocation 的方法,然后设置新的 SMS 消息(TextMessage对象)。问题是 SMS 线程只能返回原始发件人的地址(回复),我需要使用 GPS 线程以便为 SMS 消息设置有效负载。

所以现在我有 2 个方法使用同一个对象(TextMessage 对象),但我想确保第一个方法(SMS 地址 setter )在 GPS 线程运行时不会更改地址获取要设置的 GPSLocation。

可以在 ReceivedCommand() 中同步一个 block :

  • 将地址添加到TextMessage对象,
  • 运行 GPS 线程
  • 让GPS线程调用第二个方法(ReceivedLocation())
  • 然后让该方法更改 TextMessage 对象?

最佳答案

首先,线程创建是昂贵的。您最好使用线程池(可以在java.util.concurrent 包(一个ExecutorService)中找到)并进行farming你的工作到那个

在共享对象上使用synchronized 将确保没有两个线程可以inside synchronized block 同时。但是,如果我在 synchronized block 中创建并启动一个线程,我(即第一个线程)可能会在第二个线程实际启动之前退出该 block :

final TextMessage msg = //...
Thread t = new Thread(r);
synchronized (msg) {
t.start();
} //the other thread is still running and now this thread has not synchronized on the msg

然后你的处理器r:

Runnable r = new Runnable() {
public void run() {
synchronized (msg) { //only any use if readers are alse sync-ed
msg.setGpsLocation(findGpsLocation(msg));
}
}
}

只要 TextMessage 对象是线程安全的(即字段访问是同步的),您就应该没问题,不需要显式同步这样

Note that synchronized is semantically important not just from the perspective of thread-scheduling but also from the fact that it affects data visibility between threads (for example, without synchronization, you cannot be sure that modifications made in one thread will be visible to another).

修改我的答案以使用 ExecutorService:

final TextMessage msg = //...
ExecutorService worker = Executors.newSingleThreadedExecutor();
Future<?> f = worker.submit(r); //the future represents the work

在这里,r 看起来像:

Runnable r = new Runnable() {
public void run() {
GpsLocation loc = findGpsLocation(msg);
msg.setGpsLocation(loc); //the setter is synchronized
}
}

应该同步的是 setGpsLocation 方法(连同 getter 和两个线程都需要的任何其他字段访问 )。请注意,如果您需要跨字段的原子性,那么简单地同步字段访问并不总是足够的。例如,您可能希望根据另一个字段的值有条件地更新一个字段 - 在这种情况下,只要您在字段访问期间显式同步,一切都会好的:

synchronized (msg) {
if (msg.getGpsLocation().isIn(AMERICA))
msg.append(" DUDE!")
}

关于java - 如何在父对象中同步(d)方法和修改对象的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1264532/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com