加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在JRuby中使用|| =和=(jruby-lint警告)

发布时间:2020-12-17 02:46:25 所属栏目:百科 来源:网络整理
导读:当我在我的(Rails)应用程序上运行 jruby-lint时,我会得到以下几个: Non-local operator assignment is not guaranteed to be atomic 哪个代码看起来像这样: def foo @foo ||= Foo.newend 或这个: config.assets.precompile += %w( email/email.css ) 其中
当我在我的(Rails)应用程序上运行 jruby-lint时,我会得到以下几个:

Non-local operator assignment is not guaranteed to be atomic

哪个代码看起来像这样:

def foo
  @foo ||= Foo.new
end

或这个:

config.assets.precompile += %w( email/email.css )

其中一些在app /中,其中一些在config /中.我猜这个警告只与左边的东西是一个数组的情况有关,为了修复它我应该使用Threadsafe::Array

我需要改变哪些类型的这些东西?

解决方法

在jruby中,像|| =这样的复合表达式不是以原子方式执行的.当你写:

foo ||= 'bar'

内部实际执行的内容如下:

1. unless foo
2.   foo = 'bar'
3. end

因为第1行和第2行是单独评估的,所以在多线程应用程序中可以通过这两者之间的不同线程来更改状态,例如:

thread 1: foo ||= 'bar'
thread 2: foo ||= 'baz'

其执行如下:

# foo has not been set yet
1. thread 1: unless foo
2. thread 2: unless foo
3. thread 1:   foo = 'bar'
4. thread 2:   foo = 'baz' 
# ...

请注意,foo最终会被第二个线程重新分配给’baz’,即使它已经有值.使用=同样有问题,因为:

thread 1: x += 1
thread 2: x += 1

将执行如下:

# x starting value of 0
1. thread1: tempvar = x + 1 # 1
2. thread2: tempvar = x + 1 # 1
3. thread1: x = tempvar     # 1
4. thread2: x = tempvar     # 1

因此,在两次操作之后x应为2,但实际上只增加一次.

如果您在jruby中运行单线程应用程序/脚本,则这不是问题.如果您要使用多个线程运行,那么如果这些操作用于由多个线程访问的变量,则在这些线程的执行环境中使用这些操作是不安全的.

在线程安全很重要的环境中,您可以通过将操作包装在互斥锁中或使用确保特定操作的线程安全性的原语来解决此问题.

此外,atomic gem可以与jRuby一起使用,以确保检查和检测的原子性.更新操作.我不确定它是否支持数组.

More information about managing concurrency in jRuby.

希望这可以帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读