生産者と消費者とsynchronized
2008/03/25
java
synchronized
Javaです。
生産者と消費者の実験のためのコード。
スタックに生産者がつんでいくのを消費者がpopして減らしていくというイメージ。
お互い壱秒休んで作業して休んで作業の繰り返しです。
import java.util.Stack;
public class TestT4 {
public static void main(String[] args) {
final Stack<Integer> stack = new Stack<Integer>();
Runnable consumer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
synchronized (stack) {
if (!stack.isEmpty())
stack.pop();
}
}
}
};
Runnable producer = new Runnable() {
int cnt = 0;
public void run() {
while (true) {
sleep(1000);
synchronized (stack) {
stack.push(cnt++);
}
}
}
};
Runnable observer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
System.out.println("" + stack);
}
}
};
new Thread(producer).start();
new Thread(producer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(observer).start();
}
static void sleep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestT4 {
public static void main(String[] args) {
final Stack<Integer> stack = new Stack<Integer>();
Runnable consumer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
synchronized (stack) {
if (!stack.isEmpty())
stack.pop();
}
}
}
};
Runnable producer = new Runnable() {
int cnt = 0;
public void run() {
while (true) {
sleep(1000);
synchronized (stack) {
stack.push(cnt++);
}
}
}
};
Runnable observer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
System.out.println("" + stack);
}
}
};
new Thread(producer).start();
new Thread(producer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(observer).start();
}
static void sleep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
まずいコードです。
消費者の数が増える例外をだす可能性が増えます。
でる例外は、java.util.EmptyStackExceptionです。
stackが空ではなかったらpopするとしているのですが、空ではないと判断した直後で別の消費者がpopしてしまう可能性があります。
import java.util.Stack;
public class TestT4 {
public static void main(String[] args) {
final Stack<Integer> stack = new Stack<Integer>();
Runnable consumer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
if (!stack.isEmpty())
stack.pop();
}
}
};
Runnable producer = new Runnable() {
int cnt = 0;
public void run() {
while (true) {
sleep(1000);
stack.push(cnt++);
}
}
};
Runnable observer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
System.out.println("" + stack);
}
}
};
new Thread(producer).start();
new Thread(producer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(observer).start();
}
static void sleep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestT4 {
public static void main(String[] args) {
final Stack<Integer> stack = new Stack<Integer>();
Runnable consumer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
if (!stack.isEmpty())
stack.pop();
}
}
};
Runnable producer = new Runnable() {
int cnt = 0;
public void run() {
while (true) {
sleep(1000);
stack.push(cnt++);
}
}
};
Runnable observer = new Runnable() {
public void run() {
while (true) {
sleep(1000);
System.out.println("" + stack);
}
}
};
new Thread(producer).start();
new Thread(producer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(consumer).start();
new Thread(observer).start();
}
static void sleep(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
: