我目前想實現應用程序與機器溝通,並應主要工作如下:循環屏障重用?
- 程序將消息發送到服務器(在這種情況下,第一個255個字節的文件)。
- 機器以「成功接收消息」或「接收消息錯誤 」響應作出響應。
- 根據機器的響應,程序必須決定是否發送下一條消息(下一個255字節)或不是(最後一條消息的錯誤,必須重新開始)。
- 等等程序需要發送的每條消息(取決於文件的大小)。
所以,我們認爲有一個線程來做發送,另一個做接收,因爲我們有一個API來註冊一個類作爲從機器接收消息的類(只需通過實現一個接口),並且將消息發送到機器的方法不是阻塞類型,所以等待機器響應的方法,以便程序可以決定在響應到達後要執行什麼操作。
因此,我們需要以某種方式同步這兩個線程,因爲可以確定他們將交換多少條消息,這使我們嘗試了一個CyclicBarrier。這是用於測試的CyclicBarrier是否會幫我們解決這個問題的代碼(程序實際上並未使用插座與機器溝通,這只是用於測試的屏障):
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class BlockingTest{
private CyclicBarrier barrier;
class Receiver implements Runnable{
@Override public void run(){
try{
ServerSocket ss = new ServerSocket(8080);
while(!barrier.isBroken()){
System.out.println("Waiting message...");
Socket response = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
response.getInputStream()));
System.out.printf("Received: %s\n", br.readLine());
barrier.await();
}
}catch(InterruptedException | BrokenBarrierException |
IOException ex){
System.err.println(ex.getMessage());
}
}
}
public BlockingTest(){
this.barrier = new CyclicBarrier(2, new Runnable(){
@Override public void run(){
System.out.println("done.");
}
});
new Thread(new Receiver()).start();
try{
Socket sender = new Socket("localhost", 8080);
PrintWriter pw = new PrintWriter(sender.getOutputStream(), true);
for(int i = 0; i < 3; i++){
System.out.println("Sending message:");
pw.println("Message!");
this.barrier.await();
}
}catch(InterruptedException | BrokenBarrierException | IOException ex){
System.err.println(ex.getMessage());
}
}
public static void main(String[] arg){
new BlockingTest();
}
}
此代碼工作如果我們只發送一條消息(BlockingTest()構造函數中的塊爲no,只是發送消息),但在添加for塊之後,它無法按預期工作。它只能是第一次,那麼它掛起:
Waiting message...
Sending message:
Received: Message!
done.
Waiting message...
Sending message:
的問題是:
如何使屏障可重用?是自動的還是它有 手動完成?
由於我錯過了插座(或屏障代碼),程序是否掛起?
由於發送和接收是按順序完成的,所有工作都可以在單線程中完成。兩個線程是不必要的複雜和浪費資源。 –
我是這麼認爲的,但是我們遇到了一些問題,試圖使它成爲順序的,因爲標記爲接收消息的對象通過一個硬件中斷來通知傳入消息,而我們無法控制這個硬件中斷,程序等待機器的響應,所以有時會丟失信息;在我們的例子中是不可接受的,因爲這些文件實際上是用於智能卡芯片的操作系統。 –
你在說什麼硬件中斷?你顯示的文本只使用標準的Socket和ServerSocket用法。然後,在測試中,單一屏障用於客戶端和服務器線程。實際上,客戶端和服務器運行在不同的進程中,並且不能訪問同一個對象。 –