みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ExecutorService.newFixedT

はじめまして。

タイトルの通り、ExecutorService.newFixedThreadPool()で生成されたスレッド達の名前を取得しようとしています。
プログラムは以下です。


[SharedObject.java]
import java.lang.Math;
import java.util.Random;

public class SharedObject {

private int i,x;
private final int[] array = new int[2500000];
private final Random r = new Random();
private long t0=0L,t1=0L;

public void work() {
t0 = t1 = System.nanoTime();
while((t1-t0) < 3000000000L) {
synchronized (this) {
x = r.nextInt(2500000);
array[x] = array[x] + 1;
}
t1 = System.nanoTime();
}
}
}



[Task.java]
public class Task implements Runnable {

private SharedObject obj;

Task(SharedObject obj) {
this.obj = obj;
}

public void run() {
for(int i=0; i<3; i++) {
this.obj.work();
}
}
}



[BenchMark.java]
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.io.*;
import java.util.Random;

public class BenchMark {
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(12);
Random rnd = new Random();
int num, rnum;

SharedObject obj1 = new SharedObject();
SharedObject obj2 = new SharedObject();
SharedObject obj3 = new SharedObject();
SharedObject obj4 = new SharedObject();

for(int i=0; i<500; i++) {
num = rnd.nextInt(4);
if(num == 0) {
ex.execute(new Task(obj1));
}
else if(num == 1){
ex.execute(new Task(obj2));
}
else if(num == 2){
ex.execute(new Task(obj3));
}
else {
ex.execute(new Task(obj4));
}
}

ex.shutdown();
}
}



BenchMark.javaで12個のスレッドプールと4つのタスク(SharedObject.java)を生成しています。

各タスクから「今どのスレッドが自分にアクセスしているか」を確認するために、スレッド名を表示する機構を作りたいです。

具体的には、SharedObjectクラスの中の synchronized で囲われている部分に、その時点でロックを保持しているスレッドの getName() メソッドを呼び出すようなプログラムが書きたいと思ってるのですが、どのように書いたらいいのでしょうか?

よろしくお願いします。



※できるだけ早く回答をいただきたいので、他掲示板にもマルチポストさせていただいています。不快に思われた方にお詫び申し上げます。

投稿日時 - 2011-02-26 04:39:08

QNo.6550997

すぐに回答ほしいです

質問者が選んだベストアンサー

> その時点でロックを保持しているスレッドの getName() メソッドを呼び出す

ロックを保持している = synchronized ブロックの中を実行している
と考えてよいなら、単に synchronized ブロックの中に
System.out.println(Thread.currentThread().getName());
と書けば良いのでは?


ちなみに SharedObject はスレッドセーフになっていませんよね?
t0 や t1 が volatile でなく同期化無しの参照・変更があるので、他のスレッドでの変更が中途半端に見えたり見えなかったりする可能性が有りますよね。ただし、他のスレッドでの変更が正確に反映されたとしても、それが期待される動作とも思えません。
t0,t1,xはローカル変数にすべきでは?

参考URL:http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Thread.html#currentThread%28%29

投稿日時 - 2011-02-26 17:30:14

お礼

ありがとうございました。
APIドキュメントは何回も見ていたのですが、currentThread()だけ見落としていました
なんとも恥ずかしや...(^^;

しかもスレッドセーフでない点まで指摘していただいて感謝しております。
よく考えてみたら、t0,t1,xはスレッドセーフでないですね。
かなり基本的な事でつまづいていたようです。

ありがとうございました。

投稿日時 - 2011-02-27 04:52:37

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)