[java]またキューして実行
2009/02/25
java
スレッド
Javaです。
またふただび、キューして実行。
以前も書いたけど、
どうも、wait,notify,が頭の中ですっきりしないので。
synchronizedされているところでしかwait,notifyできないです。
waitすると他のブロックされているスレッドが実行されます。
wait()はsynchronizedブロックの中で使用する。
wait()を呼び出すと、呼び出したスレッドはそこで実行を停止し、他のスレッドがsynchronizedの中に入って実行できる。
後から実行されたスレッドがnotify()を呼び出すと、そのスレッドがsynchronizedブロックから抜けた後にwait()を呼び出したスレッドが再実行される。Javaスレッドメモ(Hishidama's Java thread Memo)
上記の引用の通りですが、この「synchronizedブロックから抜けた後にwait()を呼び出したスレッドが再実行される」が理解できず、苦しみましたが、いまなら、なんとか頭でシュミレートできそうな気がします。
人に説明しろといわれたら、心もとないです。
またコード。
package th;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestEasyQue {
public static void main(String[] args) {
final Q q = new Q();
JFrame frame = new JFrame() {
{
JPanel panel = new JPanel() {
{
add(new JButton("start") {
{
addActionListener(new ActionListener() {
int i = 0;
@Override
public void actionPerformed(ActionEvent e) {
q.enqueue("addA " + i++);
q.enqueue(new Q.IExecutable() {
@Override
public void exec() {
try {
System.out
.println("*** >_<!! sleep!!");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
});
}
});// end add
}
};
getContentPane().add(panel);
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
};
frame.setVisible(true);
}
static class Q {
LinkedList list = new LinkedList();
Thread worker = new Thread();
public Q() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (Q.this) {
while (!(0 < list.size())) {
try {
// System.out.println("i am wait...");
Q.this.wait();
} catch (Exception e) {
e.printStackTrace();
}
}//
}// synchronized
Object o = dequeue();
if (o instanceof IExecutable) {
exec((IExecutable) o);
continue;
}
System.out.println("*** " + o.toString());
}// while
}
}).start();
}
public synchronized void enqueue(Object o) {
list.addFirst(o);
notifyAll();
}
public synchronized Object dequeue() {
return list.removeLast();
}
void exec(IExecutable executable) {
try {
executable.exec();
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable e) {
e.printStackTrace();
}
}
interface IExecutable {
public void exec();
}
}
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestEasyQue {
public static void main(String[] args) {
final Q q = new Q();
JFrame frame = new JFrame() {
{
JPanel panel = new JPanel() {
{
add(new JButton("start") {
{
addActionListener(new ActionListener() {
int i = 0;
@Override
public void actionPerformed(ActionEvent e) {
q.enqueue("addA " + i++);
q.enqueue(new Q.IExecutable() {
@Override
public void exec() {
try {
System.out
.println("*** >_<!! sleep!!");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
});
}
});// end add
}
};
getContentPane().add(panel);
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
};
frame.setVisible(true);
}
static class Q {
LinkedList list = new LinkedList();
Thread worker = new Thread();
public Q() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (Q.this) {
while (!(0 < list.size())) {
try {
// System.out.println("i am wait...");
Q.this.wait();
} catch (Exception e) {
e.printStackTrace();
}
}//
}// synchronized
Object o = dequeue();
if (o instanceof IExecutable) {
exec((IExecutable) o);
continue;
}
System.out.println("*** " + o.toString());
}// while
}
}).start();
}
public synchronized void enqueue(Object o) {
list.addFirst(o);
notifyAll();
}
public synchronized Object dequeue() {
return list.removeLast();
}
void exec(IExecutable executable) {
try {
executable.exec();
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable e) {
e.printStackTrace();
}
}
interface IExecutable {
public void exec();
}
}
}
: