StudentAccount4
StudentAccount4

Reputation: 186

concurrent run using ListBlockingQueue thread is getting blocked for some reason

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):

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

Answers (2)

StudentAccount4
StudentAccount4

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

Andy Turner
Andy Turner

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

Related Questions