Spring是否是RestTemplate线程安全的?那是
RestTemplate多个连接可以安全共享的策略对象.要么RestTemplate连接对象(如数据库连接),在使用时无法共享,并且需要为每个连接重新创建或池化.这似乎是一个非常基本的问题,但我找不到明确的确认.
假设我有一个类本身正确同步:
public class SyncClass {
private int field;
public synchronized void doSomething() {
field = field * 2;
}
public synchronized void doSomethingElse() {
field = field * 3;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我需要引用该类的实例,在线程之间共享,我仍然需要声明该实例是volatile还是final,我是对的吗?如:
public class MainClass { // previously OuterClass
public static void main(String [ ] args) {
final SyncClass mySharedObject = new SyncClass();
new Thread(new Runnable() {
public void run() {
mySharedObject.doSomething();
}
}).start();
new Thread(new Runnable() {
public void run() {
mySharedObject.doSomethingElse();
}
}).start(); …Run Code Online (Sandbox Code Playgroud) 我希望这不是一个愚蠢的问题......
我的代码中的代码类似于以下代码:
public class ConfigStore {
public static class Config {
public final String setting1;
public final String setting2;
public final String setting3;
public Config(String setting1, String setting2, String setting3) {
this.setting1 = setting1;
this.setting2 = setting2;
this.setting3 = setting3;
}
}
private volatile HashMap<String, Config> store = new HashMap<String, Config>();
public void swapConfigs(HashMap<String, Config> newConfigs) {
this.store = newConfigs;
}
public Config getConfig(String name) {
return this.store.get(name);
}
}
Run Code Online (Sandbox Code Playgroud)
处理请求时,每个线程将使用getConfig()函数从存储中请求使用配置.但是,定期(最有可能每隔几天),使用swapConfigs()函数更新和交换配置.调用swapConfigs()的代码不会保留对它传入的Map的引用,因为它只是解析配置文件的结果.
volatile商店实例变量仍然需要关键字吗?volatile关键字带来任何潜在的性能瓶颈,我应该知道的或可避免因为读取的速度大大超过写入的速度?非常感谢,
我的问题涉及在Java中安全发布字段值(这里讨论Java多线程和安全发布).
据我了解,如果出现以下情况,可以安全地读取字段(意味着从多个线程访问将看到正确的值):
如果我的理解是正确的,那么下面的类不应该是线程安全的,因为初始值是在没有这些特性的情况下编写的.但是我觉得很难相信我需要制作,first volatile即使它只是从一个synchronized方法访问.
public class Foo {
private boolean needsGreeting = true;
public synchronized void greet() {
if (needsGreeting) {
System.out.println("hello");
needsGreeting = false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?以上代码是否正确,如果是,为什么?或者在这种情况下,除了从方法访问它之外,还需要制作first volatile或使用final AtomicBoolean类似的东西.synchronized
(只是为了澄清,我知道,如果初始值是用synchronized方法编写的,即使没有volatile关键字,它也是线程安全的.)
HashMap我的程序中有一个由多个线程访问,偶尔由一个线程设置.
例如:
Map<String, String> myMap = new HashMap<String, String>();
Run Code Online (Sandbox Code Playgroud)
这可以通过多个线程访问.每小时一次,一个线程调用:
myMap = myRefreshedVersionOfTheMap;
Run Code Online (Sandbox Code Playgroud)
所以我的问题是这是否是线程安全的.如果两个映射始终都有密钥"importantKey",那么读取线程是否可以在"importantKey"不存在时访问映射?
编辑:
感谢答案,我意识到这个问题实际上是独立的HashMap.这是一个关于对象引用分配的问题.
java multithreading reference thread-safety java-memory-model
可以在以下概念Java示例中:
public class X implements Runnable {
public volatile Object x = new Object();
@Runnable
public void run() {
for (;;) {
Thread.sleep(1000);
x = new Object();
}
}
}
Run Code Online (Sandbox Code Playgroud)
x永远是null从另一个线程读取?
额外奖励:我是否需要将其声明为volatile(我并不关心该值,将来某个时候它将是新分配的值并且永远不会为空)
当我在类中使用字段注入时,如下所示:
@Inject
private MyClass myField;
Run Code Online (Sandbox Code Playgroud)
我可以对这个领域的" 安全出版 "状态做出任何假设吗?或者换一种说法,假设MyClass本身是线程安全的,那么使用这个字段时我应该注意哪些并发风险?
我的直觉通常是尽可能创建所有字段final,但这不适用于字段注入.当然,我可以使用构造函数注入,但是我通常最终只需要为代理创建一个额外的"假"no-args构造函数.没有太大问题,但使用现场注入更方便.另一种选择可能是将该字段标记为易变(或甚至使用锁定......),但这是否真的有必要?
JSR-299规范似乎没有回答这个问题.我在像Weld这样的实现上使用CDI.
我知道你可以安全地发布一个非线程安全的对象,方法是将一个final或一个volatile字段的引用写入,稍后将被其他一个线程读取,前提是在发布时,创建该对象的线程会丢弃对它的引用,以便它不能再干扰或不安全地观察对象在另一个线程中的使用.
但在这个例子中,没有显式final字段,只有final局部变量. 如果调用者丢弃其引用unsafe,这是安全的出版物吗?
void publish(final Unsafe unsafe) {
mExecutor.execute(new Runnable() {
public void run() {
// do something with unsafe
}
}
}
Run Code Online (Sandbox Code Playgroud)
我发现了一些Q&As,就像这个一样,暗示final局部变量被隐式"复制"到匿名类中.这是否意味着上面的例子等同于此?
void publish(final Unsafe unsafe) {
mExecutor.execute(new Runnable() {
final Unsafe mUnsafe = unsafe;
public void run() {
// do something with mUnsafe
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑以澄清:
Unsafe 可能是什么,但说它是这样的:
public class Unsafe {
public int x;
}
Run Code Online (Sandbox Code Playgroud)
并且mExecutor是满足合同的任何东西Executor.
为什么Bill Pugh的Singleton设计模式线程安全?
public class Logger {
private Logger() {
// private constructor
}
// static inner class - inner classes are not loaded until they are
// referenced.
private static class LoggerHolder {
private static Logger logger = new Logger();
}
// global access point
public static Logger getInstance() {
return LoggerHolder.logger;
}
//Other methods
}
Run Code Online (Sandbox Code Playgroud) java ×10
volatile ×3
concurrency ×2
cdi ×1
reference ×1
rest ×1
singleton ×1
spring ×1
synchronized ×1
weld ×1