1

Javaでは、キャスト例外が発生します。

java.lang.ClassCastException: java.util.concurrent.ThreadPoolExecutor$Worker
incompatible with com.myco.TaskListEntry
at com.myco.JobThreadFactory.newThread(JobThreadFactory.java:17)

コードは次のとおりです。

public class JobThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        TaskListEntry entry = (TaskListEntry)r;   //<== Cast exception!
        return new Thread(r, "Thread for " + entry.toString());
    }
}

@DisallowConcurrentExecution
public class WorksheetSessionJob implements Job {
    private List<TaskListEntry> taskListEntries;

    @Override
    public void execute(JobExecutionContext jobContext) throws JobExecutionException {
        ThreadFactory threadFactory = new JobThreadFactory();
        ExecutorService executor = Executors.newCachedThreadPool(threadFactory);
        for( TaskListEntry nextEntry : getWorkListEntries() ) {
            executor.execute(nextEntry);
        }
    }

    private List<TaskListEntry> getWorkListEntries() {
        List<TaskListEntry> entries = new ArrayList<TaskListEntry>();

        // TODO Get rows from DB - for now, make something up to test with
        //-- beginning of fake data creation ----------
        TaskListEntry entry = new TaskListEntry("0022", "04590150560", "DI_MODULAR", 1);
        entries.add(entry);
        entry = new TaskListEntry("0007", "04590150560", "DI_MODULAR", 2);
        entries.add(entry);
        //-- end of fake data creation ----------------

        return entries;
    }

}

public class TaskListEntry implements Runnable {
    private String  worksheetNumber;
    private String  specimenNumber;
    private String  instrumentName;
    private int     id;

    public TaskListEntry(String worksheetNumber, 
            String specimenNumber, String instrumentName, int id) {
        super();
        this.worksheetNumber = worksheetNumber;
        this.specimenNumber = specimenNumber;
        this.instrumentName = instrumentName;
        this.id = id;
    }

    @Override
    synchronized public void run() {
        // executor in my Job should have created a thread for me to run in
        //-- TESTING ONLY -------------
        try {
            Thread.sleep(10000);    //force execution to another thread?
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //-- END OF TESTING -----------
    }

}

TaskListEntryランナブルが送信されないのはなぜですか?そのクラスの値を使用して、対応するスレッドに名前を付ける必要があります。私は何が間違っているのですか?!

4

1 に答える 1

4

スレッド ファクトリが呼び出されたときにクラスRunnableに関連付けられていないため、キャストの問題が発生しています。ThreadPoolExecutor$Workerこれは、インスタンスを保持するWorker Runnable内部からタスクをデキューする内部エグゼキュータ クラスです。設計上、タスクを特定のスレッドに関連付けることはできません。100k のタスクをキューに送信する場合、100k のスレッドを生成することは望ましくありません。これがスレッドプールを使用するポイントです。BlockingQueueTaskListEntry

どのスレッドがどのタスクを処理しているかを何らかの方法で追跡しようとしている場合は、メソッドThread.currentThread().getId()内で thread-id ( ) をログに記録することをお勧めします。TaskListEntry.run()しかし、スレッド名で各タスクを何らかの方法で確認しようとしている場合、スレッドプールがどのように機能するかを理解していません。通常、a を使用しThreadFactoryてプール スレッドに名前を設定し、プール名を識別します。ここでは、次のような"TaskListEntry pool-1"ものが適切なスレッド名になります。

名前に関して達成しようとしていることについて詳しく説明していただければ、より多くのサポートを提供できる可能性があります。

于 2013-02-27T22:13:59.617 に答える