JRubyで並列実行するにはコツがいるということで、synchronizeを利用しない方法を紹介する。こんなの↓が話題。
str = ''
max = 1000
(1..4).map{|e|
Thread.new(e){|ti|
max.times{
str << ti.to_s
}
}
}.each{|t| t.join}
p str
% jruby tmp.rb
System.java:-2:in `java.lang.System.arraycopy': java.lang.ArrayIndexOutOfBoundsException: null (NativeException)
from ByteList.java:198:in `org.jruby.util.ByteList.append'
from ByteList.java:189:in `org.jruby.util.ByteList.append'
from RubyString.java:714:in `org.jruby.RubyString.cat'
誰の責任で同期化するかは仕様で定められているべきじゃないのかとおもいつつ、修正してみる。とりあえず、org.jruby.RubyString#catをさがす。
public RubyString cat(ByteList str) {
modify();
value.append(str);
return this;
}
ここか。valueに並列でアクセスしているのが問題なんだろう。というわけで、同期化してやる。
public RubyString cat(ByteList str) {
modify();
synchronized (value) {
value.append(str);
}
return this;
}
実行してみると、きちんと動作する。
% java -jar lib/jruby-complete.jar tmp.rb "3343434344343434344343434333333333333333333333333333232323232313131311313133333313131313113131313131313131131313142424242442424244242424244242424242121212112121211414141411414141141414141141414141141411111414142424242313131311313131311313131131333333333131311313131131313131131313131131313113131313113131313113131311313131311313131311313131311313131313131313131313133131333131313434343443434343443434343443434344343434344343434344343434434343434434343434434342344343434434343434434343443433434434343434434343443434343443434343443434344343434344343434434343434434343434434343443434343443343434434343443434343443434343443434344343434344343434344343434434343434434343434434343443434343443434343443434343232331111111212121121212122323232322242442444444113333333333333333333333333333131131313331313131131313131323232323223232323223232323223232323223232323223232323223232323223232323223232323223323232232323232232323232343434343131313131131313131131313131131313131131313131131313131131313131131313131131313131131131311313131311313131311313131341233124242442424242421212121211211111111111111111111111111111111111212212121212212121212131313131331313131331313131331313131331313131331313131313313131313313131313313131313424242424424242424424444444442423232323223232323232232323232232323232313131313113131313113131313111111111144444444444444444444313131311313131313232444441322222221111324444444444444111111111111111111111111111111111113133131313131331313131313111111131124444333331111144443124412244431432433331243343434343434343434343434343433333334343434343434343434343434343434343434343434343434343142424343331331313131313131313131313131313131313133333313313131313131313131313131313131313131313131313131313133333313131313131313131313131313131313131313131313131313131414141414141414141414141414141414141414141414141414141342424242424242424242424242424242424242424242424242424222222242424242424242424242424242422222222222222222222222222222222222323343333434343434343433331311121121212111111444333323323232323232323232323232323232333333323232323232323232323232323232323232323232323232323244444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222223111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111141414141414141414141414141414141414111111141141414141414141414141414141414141414141414141414141414141411111141141414141414141414141414141414141414141414141414141414141111114442442424242424242424222424242424242424242424242424242444444444444444444444444444444444444444444444444444433333333333333333333333333333333333333333333333333333333333333323222424444443433333334344221221212121212121212121212121212121212121212121212222222121212121212121212121212121212121212121212121212121212122222221212121212121212121212121212121212121212121212121212121212122222212121212121212121212121212121212121212121212121212121212141414141414141414141414141414141414141414141414141414141411111114141414141442442424242424242424242424242424242424242424242222222424242424242424242424242424242424242424242424242424242424244443443433333333434343434343434343434343434343434343434343434444444343434343434343434343434343434343434343434343434343434344444443434343434343434343434343434343434343434343434343434343434344444443434343434343434112334344112121212121212121212222222121212121212121212121212122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222343343434343433333333333333333333333333333333333333333333333332222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
ここから並列実行でのエラーには、パッチをあてるというのが有効とわかる。

コメントする