[英]Thread safety when multiple threads accessing the same method in Java
我有這樣的方法
private handleObj(Obj obj)
{
String data = obj.getData;
String key = obj.getKey;
store(key, data);
}
如果多個線程同時調用此方法,是否將在多個線程之間共享數據值?
就像線程A通過handleString(objFromThreadA)調用此方法一樣,線程B通過handleString(objFromThreadB)調用此方法。 會不會有那的價值任何機會String data
在線程A被替換的值String data
的線程B?
-----編輯1 -----
我對這里的線程安全有些困惑。 下面的方法是來自我用於MQTT客戶端的庫的回調。
/**
* 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放在一個線程的堆棧上,並且其他任何線程都不能共享該字符串?
每個方法調用都是其自身范圍內的方法。
您不需要線程使其可見-只需使用遞歸方法即可使這一點變得清晰:
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 >
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.