JRuby+swingでスレッドを実行

JRubyのThreadを使って並列実行させるプログラムを作ってみました。
正直正しく書けているか自信がありません。

ボタンを押すと、そのボタンが10秒間だけ無効となり、カウントダウンが終わると再び有効となります。2つのボタンは非同期で動作します。

サンプルコードです。

require 'java'

%w( JFrame JPanel JButton ).each {|c| eval c+'=javax.swing.'+c}

button1 = JButton.new "Run1"
button1.add_action_listener do |event|
  button1.enabled = false
  Thread.start do
    10.downto(1).each do |i|
      button1.text = "exec(#{i})"
      sleep(1)
    end
    button1.text = "Run1"
    button1.enabled = true
  end
end

button2 = JButton.new "Run2"
button2.add_action_listener do |event|
  button2.enabled = false
  Thread.start do
    10.downto(1).each do |i|
      button2.text = "exec(#{i})"
      sleep(1)
    end
    button2.text = "Run2"
    button2.enabled = true
  end
end

panel = JPanel.new
panel.add button1
panel.add button2

frame = JFrame.new "sample"
frame.default_close_operation = JFrame::EXIT_ON_CLOSE
frame.content_pane.add panel
frame.set_size 200,80
frame.location_relative_to = nil
frame.visible = true

button1とbutton2の書き方が冗長ですけど、わかりやすいかなと思って分けました。

Thread.start doend

ここに重い処理を置けばプログラム全体はフリーズしなくて済みます。
逆にThreadを使わないとフリーズしてカウントダウンが終わるまで何もできなくなります。

感想

swingの非同期スレッドを調べてみると"invokeLater"やSwingWorker"という単語が引っ掛かるのですが、必要なのかいまいちわかりません。
Threadだけではダメなのでしょうか。
Javaのswingを触ってないのでよくわかっていません。(初心者ですみません)

ただ、ヒントとしては「Swingはスレッドセーフで作られていない」ということ、なんだと思います。
他のスレッドからbutton.textを呼ぶときとかが問題になる?のかなと。