我有这样的方法
private handleObj(Obj obj)
{
String data = obj.getData;
String key = obj.getKey;
store(key, data);
}
如果多个线程同时调用此方法,那么数据的值是否会在多个线程之间共享?
如果线程A通过handleString(objFromThreadA)调用此方法,则线程B通过handleString(objFromThreadB)调用此方法。是否有可能线程A中String data
的值被线程B中的String data
值替换?
-----编辑1 -----
我对这里的线程安全感到有些困惑。下面的方法是从我用于MQTT客户端的lib回调。
/**
* This method is called when a message arrives from the server.
*
* <p>
* This method is invoked synchronously by the MQTT client. An
* acknowledgment is not sent back to the server until this
* method returns cleanly.</p>
* <p>
* If an implementation of this method throws an <code>Exception</code>, then the
* client will be shut down. When the client is next re-connected, any QoS
* 1 or 2 messages will be redelivered by the server.</p>
* <p>
* Any additional messages which arrive while an
* implementation of this method is running, will build up in memory, and
* will then back up on the network.</p>
* <p>
* If an application needs to persist data, then it
* should ensure the data is persisted prior to returning from this method, as
* after returning from this method, the message is considered to have been
* delivered, and will not be reproducible.</p>
* <p>
* It is possible to send a new message within an implementation of this callback
* (for example, a response to this message), but the implementation must not
* disconnect the client, as it will be impossible to send an acknowledgment for
* the message being processed, and a deadlock will occur.</p>
*
* @param topic name of the topic on the message was published to
* @param message the actual message.
* @throws Exception if a terminal error has occurred, and the client should be
* shut down.
*/
public void messageArrived(String topic, MqttMessage message) throws Exception;
每次调用此方法时。我创建了一个新线程来处理message
对象,这是我从message
对象获取大量数据和密钥。当我阅读评论时,它说这个方法是同步调用的,那么这意味着消息肯定是线程安全的吗?
这是我处理邮件对象的方式。
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
try
{
handleMessage(topic, new String(message.getPayload()));
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
threadPool.execute(runnable);
}
在handleMessage(String topic,String message)中我有这样的东西:
private void handleMessage(String topic, String message)
{
JSONObject messageJson = new JSONObject(message);
//get values from JSON
String value = messageJson.get("key");
}
所以,我不确定我在这里做的是否是线程安全的。如果我将一个新分配的String(new String(message.getPayload())
)传递给我的handleMessage方法,这是否意味着新的String被放置在一个线程的堆栈上,没有其他线程可以共享该字符串?
答案 0 :(得分:2)
每个方法调用都是自己范围内的方法。
您不需要线程使其可见 - 只需使用递归方法,以明确这一点:
void middle (String s) {
println ("<" + s);
if (s.length () > 2)
middle (s.substring (1, s.length () - 1));
println (s + ">");
}
在第4行中,调用了该方法的新实例,s现在是外部s的截断版本。但是在完成内部调用后,外部s根本不受影响。
-> middle ("foobar")
<foobar
<ooba
<ob
ob>
ooba>
foobar>
对于线程,可能的碰撞(更好:不可能的碰撞)更难显示。
但问题是合法的。看看,乍一看,等效代码如何在bash中表现(对我而言,非常令人惊讶):
middle () {
s=$1
echo "< $s"
len=${#s}
if (( $len > 2 ))
then
middle ${s:1:((len-2))}
fi
echo "$s >"
}
middle "foobar"
< foobar
< ooba
< ob
ob >
ob >
ob >