gpt4 book ai didi

java - 关于多线程的一些具体问题

转载 作者:行者123 更新时间:2023-11-30 01:44:01 25 4
gpt4 key购买 nike

问题 1。如果我们考虑以下类:

public class Test {
public static LinkedList<String> list;
}

如何使变量“list”的获取/设置线程安全?

我想我可以做这样的事情:

public class Test {
private static LinkedList<String> list;

public static synchronized LinkedList<String> getList() {
return new LinkedList<>(list);
}

public static synchronized void setList(LinkedList<String> data) {
list = new LinkedList<>(data);
}
}

问题 2。

但是这有多线程安全呢?我是否必须每次都初始化一个新列表以确保其他副本不会影响该变量?

问题 3。

如果我们考虑这一点:

public class Test {
private static LinkedList<String> list;

public static synchronized void ManipulateList() {
// do stuff to 'list'
}

public static synchronized void ChangeList() {
// do more stuff to 'list'
}
}

其中“ManipulateList”和“ChangeList”方法都可能向同一列表添加或删除变量

这是线程安全的吗?这是否意味着如果线程 1 正在访问“ManipulateList”,那么线程 2 无法访问“ChangeList”,直到线程 1 完成访问“ManipulateList”为止?

我只是不确定我是否正确理解了效果。

最佳答案

问题 1。

public static LinkedList<String> list;

How would you make getting/setting thread-safe for the variable 'list'?

避免全局[可变]状态。只需摆脱它即可。

问题 2。

public class Test {
private static LinkedList<String> list;

public static synchronized LinkedList<String> getList() {
return new LinkedList<>(list);
}

public static synchronized void setList(LinkedList<String> data) {
list = new LinkedList<>(data);
}
}

But how thread-safe is this? Would I have to initialize a new list each time to ensure other copies don't affect the variable?

(我假设this你的意思是Test.list而不是传入的data,由于Java集合库,本身是可变的。

因此您始终使用持有相同的锁来访问列表。与外界打交道时,你总是在抄袭 list 。列表的成员是不可变的,因此您不需要任何深度复制。一切都好。

该方法对不涉及变量的昂贵操作持有锁,因此我们应该在这里做得更好。

public static synchronized LinkedList<String> getList() {
// The `LinkedList` list points to is never mutated after set.
LinkedList<String> local;
synchronized (Test.class) {
local = list;
}
return new LinkedList<>(local);
}

public static void setList(LinkedList<String> data) {
LinkedList<String> local = new LinkedList<>(data);
synchronized (Test.class) {
list = local;
}
}

理论上,即使没有更改,也不需要为整个副本持续持有锁。由于它是一个公共(public)锁对象(但很顽皮,但很常见),data 可以等待它暂时释放锁。显然这里并不重要,但在现实世界的情况下,它可能会导致奇怪的情况。

稍微隐晦一点的是,list 可以设置为 volatile 并消除锁。

问题 3。

    private static LinkedList<String> list;

public static synchronized void ManipulateList() {
// do stuff to 'list'
}

public static synchronized void ChangeList() {
// do more stuff to 'list'
}

Is this thread-safe? Does this mean that if thread 1 is accessing 'ManipulateList' then thread 2 is not able to access 'ChangeList' until thread 1 finishes accessing 'ManipulateList'?

是的。除此之外,可能会有 wait ,并且其中一个方法可能会间接调用另一个方法。

一般注释。

  • 删除全局[可变]状态。
  • 尽量避免共享可变对象(使共享对象保持不可变,使可变对象保持不共享)。
  • 减少代码量和持有锁的时间。
  • 复制可变输入和输出。

关于java - 关于多线程的一些具体问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58861114/

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