をマルチスレッド使用して通話同期(通知)は、Javaの後に動作していません。コードは、私はこれを読んでいた
コンシューマは、リストにオブジェクトが格納されているサーバーです。このリストの追加/削除ができます。
プロデューサは、プロデューサが停止していない場合、Consumer Serverがオブジェクト(整数)を格納している場合にのみ、データを送信します(PipedInputStream
/PipedOutputStream
)。サーバに再びオブジェクトがあると、プロデューサはデータの送信を開始します。
問題
は、私は次のメソッドを呼び出すときに、上げpublic void addInteger() {
new Thread (new Runnable() {
public void run() {
try {
System.out.println ("Add before size:" + lConsumerClient.size());
lConsumerClient.add((int)(Math.random()*100.0));
synchronized(oSignalExternal) {
oSignalExternal.notify();
}
System.out.println ("Add after size:" + lConsumerClient.size());
} catch (Exception e) { e.printStackTrace(); }
}
}).start();
}
public void removeFirst() {
new Thread (new Runnable() {
public void run() {
try {
System.out.println ("Remove before size:" + lConsumerClient.size());
if (hasInteger()) {
lConsumerClient.remove(0);
}
synchronized(oSignalExternal) {
oSignalExternal.notify();
}
System.out.println ("Remove after size:" + lConsumerClient.size());
} catch (Exception e) { e.printStackTrace(); }
}
}).start();
}
出力:
Add before size:0
Add after size:1
i:0 ->18 =218
i:0 ->18 =218
Add before size:1
i:0 ->18 =218
i:1 ->90 =290
i:0 ->18 =218
i:1 ->90 =290
Add before size:2
i:0 ->18 =218
i:1 ->90 =290
i:2 ->76 =276
Add before size:3
i:0 ->18 =218
i:1 ->90 =290
i:2 ->76 =276
i:3 ->43 =243
Remove before size:4
Remove before size:3
Remove before size:2
i:0 ->43 =243
i:0 ->43 =243
Remove before size:1
ExtSynchro$ExtClient sleeping
Remove after size:0
Remove after size:0
Remove after size:0
ExtSynchro$ExtClient sleeping
Add after size:0
Add after size:0
Add after size:0
Remove after size:0
待機して働いている通知します。
私は、コールの後に理由を知りたい:
synchronized(oSignalExternal) {
oSignalExternal.notify();
}
んが、コードが実行されませんか?あなたのexConsumerServerは常に要素を持っているので、ここで
完全なコード
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import javax.swing.*;
public class ExtSynchro extends JFrame {
JButton jbSync = new JButton("Sync");
JButton jbPlus = new JButton("+");
JButton jbMinus = new JButton("-");
JButton jbStop = new JButton("Stop");
Object oSignalExternal = new Object();
ExtServer exConsumerServer;
ExtClient exProducerClient;
PipedInputStream pSnk = new PipedInputStream();
PipedOutputStream pSrc = new PipedOutputStream();
static final String NL = System.getProperty("line.separator");
public ExtSynchro() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jbSync.addActionListener((ActionEvent e) -> {
try { pSrc.connect(pSnk); } catch (IOException ex) {}
exConsumerServer = new ExtServer();
exProducerClient = new ExtClient();
exConsumerServer.start();
exProducerClient.start();
});
jbPlus.addActionListener((ActionEvent e) -> {
exConsumerServer.addInteger();
});
jbMinus.addActionListener((ActionEvent e) -> {
exConsumerServer.removeFirst();
});
jbStop.addActionListener((ActionEvent e) -> {
exConsumerServer.stopThread();
exProducerClient.stopThread();
exConsumerServer = null;
exProducerClient = null;
});
JPanel jpButtons = new JPanel();
jpButtons.setLayout(new BoxLayout(jpButtons, BoxLayout.PAGE_AXIS));
jpButtons.add(jbSync);
jpButtons.add(jbPlus);
jpButtons.add(jbMinus);
jpButtons.add(jbStop);
add(jpButtons);
pack();
}
public static void main(String args[]) {
EventQueue.invokeLater(() -> {
new ExtSynchro().setVisible(true);
});
}
class ExtClient extends Thread {
private volatile boolean bRunning;
@Override public void run() {
bRunning = true;
while (bRunning) {
try {
synchronized(oSignalExternal) {
try {
while (exConsumerServer.hasInteger()) {
pSrc.write(200);
try { Thread.sleep(3000); } catch (InterruptedException ex) { }
}
System.out.println(getClass().getName() + "\tsleeping");
oSignalExternal.wait();
} catch (InterruptedException e2) {}
if (!bRunning) break; // To exit from synchronized
}
} catch (IOException e) {
bRunning = false;
}
}
System.out.println(getClass().getName() + "\tfinishing");
}
public void stopThread() {
bRunning = false;
synchronized(oSignalExternal) {
oSignalExternal.notify();
}
}
};
//The Consumer Server.
class ExtServer extends Thread {
private volatile boolean bRunning;
//BlockingQueue<Integer> lConsumerClient =new ArrayBlockingQueue<>(10);
java.util.List<Integer> lConsumerClient = Collections.synchronizedList(new ArrayList<>(4));
@Override public void run() {
bRunning = true;
while (bRunning) {
int iRd;
try {
while ((iRd = pSnk.read()) != -1) {
for (int i = 0; i < lConsumerClient.size(); i++) {
int n = lConsumerClient.get(i);
System.out.println ("\t\ti:" + i + " ->" + n +"\t=" + (n + iRd));
}
}
} catch (IOException e) {}
}
System.out.println(getClass().getName() + "\tfinishing");
}
public void addInteger() {
new Thread (new Runnable() {
public void run() {
try {
System.out.println ("Add before size:" + lConsumerClient.size());
lConsumerClient.add((int)(Math.random()*100.0));
synchronized(oSignalExternal) {
oSignalExternal.notify();
}
System.out.println ("Add after size:" + lConsumerClient.size());
} catch (Exception e) { e.printStackTrace(); }
}
}).start();
}
public void removeFirst() {
new Thread (new Runnable() {
public void run() {
try {
System.out.println ("Remove before size:" + lConsumerClient.size());
if (hasInteger()) {
lConsumerClient.remove(0);
}
synchronized(oSignalExternal) {
oSignalExternal.notify();
}
System.out.println ("Remove after size:" + lConsumerClient.size());
} catch (Exception e) { e.printStackTrace(); }
}
}).start();
}
public boolean hasInteger() {
return lConsumerClient.size() > 0;
}
public void stopThread() {
bRunning = false;
try { pSrc.close();pSnk.close(); } catch (IOException e) {}
}
};
}
これは、あなたが読んでくれると期待している非常にたくさんのコードです。それを[mcve]に切り落としてください。 –
また、 "私は初心者です"し、wait()とnotify()から離れてください。あなたが何をしているのかを知っていれば素晴らしいことができますが、正しく使うのは難しいです。これらを(実際にはほとんどのマルチスレッディングで)残しておけば、Javaのはるかに強固な理解が得られるでしょう。 (私は正直言って、私は本当のためにこれを使う必要はなかったと言うことができます: 'java.util.concurrent'の高水準クラスは*多く*使いやすくなりました)。 –
メインはなく、カット&ペーストは何を達成するのですか? – matt