Reputation: 186
currently, I'm working on a Projekt where I have to make a simple program using Threads
and BlockingQueue
:
The program is Caesar encoding why the LinkedBlockingQueue
well because it's an assignment :).
The Program shall read the letters from the console (including the Carriage return and the line feed char(10)
char(13)
) which will act as a flag to identify where the not-encoded letters end!.
so the queue would look something like this (assuming the shift factor is 3):
['a'->'a'->'a'->'13'->'d'->'d'->'d']
so what I did is the following:
CODE:
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>();
var encoded = new LinkedBlockingQueue<Character>();
var done = new LinkedBlockingQueue<Boolean>();
Thread t1=new Thread(()-> takeInput(letters,br));
Thread t2=new Thread(()->encode(letters,encoded));
Thread t3=new Thread(()-> send(encoded,done));
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println(done.take());
}
private static void takeInput(BlockingQueue<Character>letters, BufferedReader br ) {
System.out.println("Enter your input!.");
int temp;
try {
while((temp=br.read())!=-1) {
letters.put((char) temp);
System.out.println("added "+ temp+ " and letters queue is "+letters);
if (temp == CR || temp == LF){
break;
}
}
}catch (IOException | InterruptedException e){ e.printStackTrace(); }
finally {
try {
br.close();
} catch (IOException e) { e.printStackTrace(); }
}
}
public static void encode(BlockingQueue<Character>letters, BlockingQueue<Character>encoded) {
try {
char tempLetter;
while(!letters.isEmpty()){//dont know why its not going in here!!!! BLOCKED HERE debugger dont want to get in here!
System.out.println("inside encode");
tempLetter=letters.take();
if (tempLetter == CR ||tempLetter ==LF){
encoded.put(tempLetter);
break;
}else if (tempLetter == ' ' || tempLetter == '.') {
encoded.put(tempLetter);
}else if (cap(tempLetter) < 'X') {
encoded.put((char)(tempLetter+SHIFT_FACTOR));/
}else{
encoded.put((char)(tempLetter - OFFSET));
}
}
}catch (InterruptedException e) { e.printStackTrace(); }
}
private static Character cap(Character temp) {
return temp >= 'a' ? Character.toUpperCase(temp):temp;/
}
private static void send( BlockingQueue<Character> encoded, BlockingQueue<Boolean> done){
try {
char temp=encoded.take();
while (!encoded.isEmpty()){
System.out.println("stuck in encode!");
if(temp==CR || temp==LF)
break;
System.out.print(temp);
temp=encoded.take();
}
done.put(true);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Desired OUTPUT
Enter your input!.
aaaa
started encoding
the encoded elements are : -> dddd
The output I'm getting: !
Enter your input!.
aaa
added 97 and letters queue is [a]
added 97 and letters queue is [a, a]
added 97 and letters queue is [a, a, a]
added 10 and letters queue is [a, a, a,
]
(the program is on hold without and doesn't want to enter the while loop in the encrypt!!!!)
The prof gave us a GO code to use it as Reference to be able to realize the functions :
here is a link to the go code on pastebin
feel free to suggest anything :)
Upvotes: 2
Views: 61
Reputation: 186
The solution
Mainly, I had to correct the loop condition and use each of take()
, put()
, offer()
correctly.
plus, benefiting from the advice of the user @Andy Turner of not using Iterators nor enhanced for loops.
Further reference for learning the LinkedBlockingQueue:
the methods look like this now:
private static void encode(BlockingQueue<Character>letters,BlockingQueue<Character> encoded) {
System.out.println("started encoding");
try {
char toEncode;
while (true) {
toEncode=letters.take();
if (toEncode == ' ' || toEncode == '.'){
encoded.offer(toEncode);
}else if (toEncode == CR ||toEncode ==LF){
encoded.offer(toEncode);
break;//reached our flag!.
}else if (cap(toEncode) < 'X') {
encoded.offer((char)(toEncode+SHIFT_FACTOR));
}else{
encoded.offer((char)(toEncode - OFFSET));
}
}
} catch (InterruptedException e) { e.printStackTrace(); }
}
private static void send( BlockingQueue<Character> encoded, BlockingQueue<Boolean> done){
try {
char temp;
while(true){
temp=encoded.take();
if (temp==CR || temp==LF)
break;
System.out.print(temp);
}
System.out.println();
done.offer(true);//no need to use put() though.
} catch (InterruptedException e) { e.printStackTrace(); }
}
Upvotes: 1
Reputation: 140319
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
You start a thread, then wait for it to finish before starting the next.
Put all the joins after the starts:
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
Upvotes: 4