| <発生環境> | |
|---|---|
| OS | RedHatLinux6.1/6.2 |
| JDK | JDK1.3 |
| Vender | Sun |
- <A12-1>
- 1つのlockオブジェクトに対して、複数のThreadがwait()していることが原因です。
lockで一度に待機するThreadを1つにすることで解決できます。
また、lockに複数のThreadが待機している場合、lock.notify()で処理を再開するThreadは任意となることに注意してください。
| <発生環境> | |
|---|---|
| OS | RedHatLinux6.1/6.2 |
| JDK | JDK1.3 |
| Vender | Sun |
| <発生環境> | |
|---|---|
| OS | Solaris2.6 |
| JDK | JRE1.3 |
| Vender | Sun |
Jakarta Commons HttpClientをマルチスレッド環境で利用時に想定よりもパフォーマンスが向上しません。
※Java SE 5 で動作確認を行いました。
| <発生環境> | |
|---|---|
| OS | Windows XP |
| JDK | any |
(例)
1.ホストAへリクエスト送信
2.ホストBへリクエスト送信
3.ホストAへリクエスト送信 ...
そこで、複数のホストへの接続を行うアプリケーションにおいて、ScheduledExecutorServiceを利用して、一定周期での処理を行うプログラムを作成しましたが、
思い通り動いてくれません。
10秒毎にTaskを実行するプログラムを作成したところ、
以下の通り、開始時間が徐々にずれていってしまいます。
Task0 の2回目の実行開始時刻は、「11010」程度にしたいです。
Task0 Start (1014)
Task0 End (1514)
Task1 Start (1514)
Task1 End (2029)
Task2 Start (2029)
Task2 End (2529)
Task0 Start (11513)
Task0 End (12013)
Task1 Start (12029)
Task1 End (12543)
Task2 Start (12543)
Task2 End (13044)| <発生環境> | |
|---|---|
| OS | Any |
| JDK | JDK5.0以降 |
| Vender | Sun |
Task0 Start (1014)
Task0 End (1514)
Task1 Start (1514)
Task1 End (2029)
Task2 Start (2029)
Task2 End (2529)
Task0 Start (11018)
Task0 End (11518)
Task1 Start (11518)
Task1 End (12033)
Task2 Start (12033)
Task2 End (12533)
参考:ScheduledExecutorService service
= Executors.newSingleThreadScheduledExecutor();
long start = System.currentTimeMillis();
for (int index = 0; index < 3; index++){
Task task = new Task(index, start);
service.scheduleAtFixedRate(task,
1000, 10000, TimeUnit.MILLISECONDS);
}
public class Task implements Runnable{
int index_;
long start_;
public Task(int index, long start){
this.index_ = index;
this.start_ = start;
}
@Override
public void run(){
System.out.print("Task"
+ this.index_ + " Start ");
System.out.println("("
+ (System.currentTimeMillis() - this.start_) + ")");
try{
Thread.sleep(500);
}catch (InterruptedException ignore){
ignore.printStackTrace();
}
System.out.print("Task" + this.index_ + " End ");
System.out.println("("
+ (System.currentTimeMillis() - this.start_) + ")");
}
}JDK1.5以降で導入されたConcurrent APIを利用して、スレッドプールを実装し、
3つの処理を並列処理させようとしましたが、
以下のように、それぞれのタスクが順次に実行されます。
Task0-0 Start (31)
Task0-1 Start (1046)
Task0-2 Start (2060)
Task1-0 Start (3075)
Task1-1 Start (4090)
Task1-2 Start (5105)
Task2-0 Start (6120)
Task2-1 Start (7134)
Task2-2 Start (8149)| <発生環境> | |
|---|---|
| OS | Any |
| JDK | JDK5.0以降 |
| Vender | Sun |
Task0-0 Start (203)
Task1-0 Start (203)
Task2-0 Start (204)
Task1-1 Start (1218)
Task0-1 Start (1218)
Task2-1 Start (1219)
Task1-2 Start (2233)
Task0-2 Start (2233)
Task2-2 Start (2234)
参考:long start = System.currentTimeMillis();
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int index = 0; index < 3; index++){
executor.execute(new Task(index, start));
}
executor.shutdown();
public class Task implements Runnable{
int index_;
long start_;
public Task(int index, long start) {
this.index_ = index;
this.start_ = start;
}
public void run(){
for (int index = 0; index < 3; index++){
long time = System.currentTimeMillis() - this.start_;
System.out.println("Task" + this.index_
+ "-" + index + " Start (" + time + ")");
try{
Thread.sleep(1000);
}catch (InterruptedException ignore){
ignore.printStackTrace();
}
}
}
}
JDK1.5以降で導入されたLinkedBlockingQueueを用いて、
以下のような処理を実行したいと考えましたが、
処理を待ち受けてくれません。
実行結果のように、Serverが処理を待ち受けずにnullを取得してしまいます。
[実行結果]
Server handles null
Client requests [ Request No. 0 ]
Client requests [ Request No. 1 ]
Client requests [ Request No. 2 ]
Client requests [ Request No. 3 ]
Server handles [ Request No. 0 ]
(略)
Client requests [ Request No. 410 ]
Server handles [ Request No. 408 ]
Client requests [ Request No. 411 ]
Server handles [ Request No. 409 ]
Server handles [ Request No. 410 ]
Server handles [ Request No. 411 ]
Server handles null
Client requests [ Request No. 412 ]
RequestQueue queue = new RequestQueue();
new ClientThread(queue).start();
new ServerThread(queue).start();
public class RequestQueue{
private BlockingQueue queue_ = new LinkedBlockingQueue();
public Request getRequest(){
Request req = queue_.poll();
return req;
}
public void putRequest(Request request){
queue_.offer(request);
}
}
※ServerThread、ClientThreadはそれぞれ、| <発生環境> | |
|---|---|
| OS | Any |
| JDK | JDK5.0以降 |
| Vender | Sun |
public class RequestQueue{
private BlockingQueue queue_ = new LinkedBlockingQueue();
public Request getRequest(){
Request req = null;
try{
req = queue_.take();
}catch (InterruptedException ignore){
ignore.printStackTrace();
}
return req;
}
public void putRequest(Request request){
try{
queue_.put(request);
}catch (InterruptedException ignore){
ignore.printStackTrace();
}
}
}
この修正の結果、実行結果は以下のようになりました。Client requests [ Request No. 0 ]
Server handles [ Request No. 0 ]
Client requests [ Request No. 1 ]
Client requests [ Request No. 2 ]
Client requests [ Request No. 3 ]
Server handles [ Request No. 1 ]
(略)
Server handles [ Request No. 430 ]
Client requests [ Request No. 432 ]
Server handles [ Request No. 431 ]
Client requests [ Request No. 433 ]
Server handles [ Request No. 432 ]
Client requests [ Request No. 434 ]
注意:本文書の内容に誤りがあり、またこの文書によって不利益を被っても、
エスエムジー株式会社は一切関知いたしません。