実装の詳細: 私はいくつかのキューをシミュレートする必要がある学校のプロジェクトに取り組んでいます。ランダムな間隔で、クライアントを生成する必要があり、クライアントは入力する 1 つのキュー (複数のキューを持つことができます) を選択し、そのキュー データ構造に追加されます。各キューには、アタッチされているキューからクライアントを削除する独自のオペレーターがあります。
問題: クライアント ジェネレーターは別のスレッドで実行されます。キューのグラフィカルな表現は、GridLayout パネルに表示される JButton の ArrayList の表現であり、1 列しかありません。クライアント (JButton) をパネルに追加しようとすると、SwingWorker の publish() を使用して新しい JButton を公開し、リストに追加したいと考えています。しかし、多くの頭痛の種と、System.out.println が何が起こっているのかを把握した後、doBackground() メソッドが終了した後にのみ、process() メソッドの System.out.println() が呼び出されることに気付きました。
ここにコード:
//run method of the ClientGenerator thread
public void run()
{
System.out.println("Into thread Generator");
SwingWorker<Void,JButton> worker=new SwingWorker<Void, JButton>()
{
int sleepTime;
@Override
protected Void doInBackground() throws Exception
{
while(checkTime())
{
try
{
sleepTime=minInterval+r.nextInt(maxInterval - minInterval);
System.out.println("Sleeping - "+sleepTime+" milis");
Thread.sleep(sleepTime);
System.out.println("Woke up,"+sleepTime+" milis elapsed");
} catch (InterruptedException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Generating client...");
newClient=new Client(clientMinService,clientMaxService,log);
System.out.println("Locking lock...");
operationsOnTheQueueLock.lock();
selectedQueueOperator=selectQueueOperator();
System.out.println("Adding new client to queue...");
selectedQueueOperator.getQueue().enqueue(newClient);
System.out.println("Publishing new JButton...");
publish(new JButton("C"+selectedQueueOperator.getClientIndicator()));
//}
// else
// {
// queueHolder.add(selectedQueueOperator.getQueueClients().get(0);
// }
System.out.println("Unlocking lock...");
operationsOnTheQueueLock.unlock();
System.out.println("Lock unlocked! Should enter while again and sleep");
}
return null;
}
@Override
public void process(List<JButton> chunks)
{
newClientButton=chunks.get(chunks.size()-1);
System.out.println("Process runs.Jbutton index="+newClientButton.getText());
newClientButton.setFont(new Font("Arial", Font.PLAIN, 10));
newClientButton.setBackground(Color.lightGray);
newClientButton.setVisible(true);
newClientButton.setEnabled(false);
clients=selectedQueueOperator.getQueueClients();
clients.add(newClientButton);
selectedQueueOperator.setQueueClients(clients);
// if(selectedQueueOperator.getQueueClients().size()>0)
// {
queueHolder=selectedQueueOperator.getQueueHolder();
queueHolder.add(clients.get(clients.size()-1));
selectedQueueOperator.setQueueHolder(queueHolder);
}
// return null; //To change body of implemented methods use File | Settings | File Templates.
};
worker.execute();
try {
worker.get();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ExecutionException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
出力:
Sleeping - 1260 milis
Woke up,1260 milis elapsed
Generating client...
Locking lock...
Adding new client to queue...
Publishing new JButton... ///here I should see "Process runs.Jbutton index=C0"
Unlocking lock...
Lock unlocked! Should enter while again and sleep
Sleeping - 1901 milis
Woke up,1901 milis elapsed
Generating client...
Locking lock...
Adding new client to queue...
Publishing new JButton...///here I should see "Process runs.Jbutton index=C1
Unlocking lock...
Lock unlocked! Should enter while again and sleep
Process runs.Jbutton index=C0 //instead, Process runs only in the end.
これは、2 回の繰り返しの基本的な例です。クライアントは時々生成する必要があるため、最初はスレッドを一定時間スリープさせます。次に、クライアント オブジェクトを生成し、ボタンを生成して JPanel コンポーネントの process() メソッドに追加します。
この最後の部分は、明らかに起こっていません。理由はありますか?SwingWorkerに関して、私は試すことができません...
前もって感謝します!
後で編集:「ロック」は次のように定義されます。
Lock lock = new ReentrantLock();
ClientsGenerator(this) クラスを管理するクラスと、キューからクライアントを削除するクラスからパラメーターとして渡されます。ArrayList& ディスプレイで操作を実行するときに、2 つを同期するために使用されます。