目前我正在做一个项目,我必须使用threads
和blockingqueue
来制作简单的程序:
该程序是凯撒编码,为什么LinkedBlockingQueue
很好,因为它是一个赋值:)。
程序应从控制台读取字母(包括回车和换行char(10)
char(13)
),这将作为标识未编码字母结束的标志!
因此队列看起来如下所示(假设移位因子为3):
['a'->'a'->'a'->'13'->d'->d'->d']
我管理使程序与线程一起工作,这些线程按顺序运行,但它应该并发运行:
所以我做了以下的事情:
代码:
import java.io.*;
import java.util.concurrent.*;
public class Caesar {
private final static int CR = 13,LF=10, SHIFT_FACTOR=3, OFFSET=23;
public static void main(String[] args) throws InterruptedException {
var br = new BufferedReader(new InputStreamReader(System.in));
var letters = new LinkedBlockingQueue<Character>();
Thread t1= new Thread(()-> takeInput(letters,br));
Thread t2= new Thread(()-> {
try {
encode(letters);
} catch (InterruptedException e) {e.printStackTrace();}
});
Thread t3 = new Thread(()-> send(letters));
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
}
private static void takeInput(BlockingQueue<Character>letters, BufferedReader br ) {
System.out.println("Enter your input!.");
int temp;
try {
while((temp=br.read())!=-1) {
letters.offer((char) temp);
if (temp == CR || temp == LF){
//continue; //for multi-line function to be cancelled by ctr+d !.
break;
}
}
}catch (IOException e){ e.printStackTrace(); }
finally {
try {
br.close();
} catch (IOException e) { e.printStackTrace(); }
}
}
private static void encode( BlockingQueue<Character>letters) throws InterruptedException {
System.out.println("started encoding");
Character toEncode;
for (Character temp : letters) {
toEncode=letters.take();
assert toEncode!=null;
if (toEncode == ' ' || toEncode == '.'){
letters.add(toEncode);
}else if (toEncode == CR ||toEncode ==LF){
letters.add(toEncode);
break;
}else if (cap(temp) < 'X') {
letters.add((char)(temp+SHIFT_FACTOR));
}else{
letters.add((char)(temp - OFFSET));
}
}
}
private static Character cap(Character temp) {
return temp >= 'a' ? Character.toUpperCase(temp):temp;//ternary operator see https://en.wikipedia.org/wiki/%3F:
}
private static void send( BlockingQueue<Character> letters){
System.out.print("the encoded elements are : -> ");
letters.forEach(temp-> System.out.print(temp.toString()));//require java 8 and above!
}
}
输出量
Enter your input!.
aaaa
started encoding
the encoded elements are : -> dddd
代码工作正常,但不并发:
使
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
会使程序行为错误!。
输出错误!
Enter your input!.
the encoded elements are : -> started encoding
aaa
(program stopped without putting nor adding anything)
教授给了我们一个GO代码,用它作为参照能够实现的功能:
这里有一个链接,指向pastebin上的go代码
你可以随意提出任何建议:)
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
启动一个线程,然后等待它完成,然后再启动下一个线程。
将所有连接放在开始之后:
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();