Making string as switch case - java

In switch case there is an error -> RUNNING, ABORTED and READY cannot be resolved to a variables. What can i do to make it work? Tried enum but it really isn't working.
Main class which i cannot edit:
public class Main {
public static void main(String[] args) throws InterruptedException {
StringTask task = new StringTask("A", 70000);
System.out.println("Task " + task.getState());
task.start();
if (args.length > 0 && args[0].equals("abort")) {
/*<- code that interrupts task after 1 sec and start a new thread
*/
}
while (!task.isDone()) {
Thread.sleep(500);
switch(task.getState()) {
//error case RUNNING: System.out.print("R."); break;
//error case ABORTED: System.out.println(" ... aborted."); break;
//error case READY: System.out.println(" ... ready."); break;
default: System.out.println("unknown state");
}
}
System.out.println("Task " + task.getState());
System.out.println(task.getResult().length());
}
}
StringTask class:
public class StringTask implements Runnable {
String string;
String result = "";
String status = "";
int x;
boolean end = false;
boolean done = false;
public StringTask(String string, int x) {
this.string = string;
this.x = x;
this.status = "CREATED";
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
public void run() {
this.status = "RUNNING";
synchronized (this.result) {
try {
for (int i = 0; i < x; i++) {
result += string;
}
this.status = "READY";
this.done = true;
} catch (Exception ex) {
this.status = "ABORTED";
this.done = false;
}
}
}
public void abort() {
this.end = true;
this.done = true;
this.status = "ABORTED";
Thread.interrupted();
}
public StringTask() {
this.status = "ABORTED";
}
public String getState() {
return this.status;
}
public boolean isDone() {
return this.done;
}
public String getResult() {
return this.result;
}
}

I just noticed that you're not allowed to edit the main class. To ameliorate your issue, you'll have to make an enum to store the status:
public enum Status {
RUNNING, ABORTED, READY
}
After changing StringTask#getState to return Status, you can use your switch statement:
switch (task.getState()) {
case RUNNING:
System.out.print("R.");
break;
case ABORTED:
System.out.println(" ... aborted.");
break;
case READY:
System.out.println(" ... ready.");
break;
default:
System.out.println("unknown state");
}

Have you tried to use Strings in switch case?
"RUNNING" instead of RUNNING etc?

It seems your assignment is to get the main class to work with Enum, to do this you have to change the StringTask class. Change the type of status to State
State status;
public StringTask(String string, int x) {
this.string = string;
this.x = x;
this.status = State.CREATED;
}
...
public State getState() {
return this.status;
}
...
enum State {
RUNNING, ABORTED, READY
}
Then your switch should work fine
switch(task.getState()) {
case RUNNING:
System.out.print("R.");
break;
case ABORTED:
System.out.println(" ... aborted.");
break;
case READY:
System.out.println(" ... ready.");
break;
default:
System.out.println("unknown state");
}

Related

Java BlockingQueue - the process doesn't want to stop

Why doesn't this process stop, i.e. follow the instructions even though it meets the "if" condition? What is the best way to break out of the loop in this case?
public class Writer implements Runnable {
Author author;
int i = 0;
public Writer(Author autor) {
this.author = autor;
}
#Override
public void run() {
while (true) {
try {
if (i == author.getInt()) {
break;
} else {
i++;
System.out.println(i);
System.out.println(author.getInt());
System.out.println("Queue txt: " + author.getQueque().take());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Stopping waiting threads on condition

I am learning multithreading. I am implementing producer and consumer problem. I am stuck on scenario where i want that when I press anything apart from integer from keyboard, all my threads should die and there is no memory in use by threads. Please have your valuable inputs to help me achieve it. Below is all the code I am using.
package com.java.concurrency;
public class ThreadSignaling {
private int i = -1;
private boolean valueSet = false;
private boolean stopFlag = false;
public void put(int value) {
synchronized (this) {
while (valueSet) {
if (stopFlag) {
System.out.println("Byeeeeeeeeeeeee");
break;
}
try {
this.wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException while waiting in put() : " + e);
}
}
this.i = value;
this.valueSet = true;
System.out.println("Value put : " + this.i);
this.notify();
}
}
public void get() {
synchronized (this) {
while (!valueSet) {
if (stopFlag) {
System.out.println("Byeeeeeeeeeeeee");
break;
}
try {
this.wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException while waiting in get() : " + e);
}
}
System.out.println("Value get : " + this.i);
valueSet = false;
this.notify();
}
}
public void finish() {
synchronized (this) {
stopFlag = true;
this.notifyAll();
}
}
}
public class Producer implements Runnable {
private ThreadSignaling sharedObj = null;
private final Scanner input = new Scanner(System.in);
public Producer(ThreadSignaling obj) {
this.sharedObj = obj;
}
#Override
public void run() {
int value = -1;
System.out.println("Press Ctrl-c to stop... ");
while (true) {
System.out.println("Enter any integer value : ");
if (input.hasNextInt()) {
value = input.nextInt();
} else {
this.sharedObj.finish();
return;
}
this.sharedObj.put(value);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("InterruptedException while sleeping" + e);
}
}
}
}
public class Consumer implements Runnable {
private ThreadSignaling sharedObj = null;
public Consumer(ThreadSignaling obj) {
this.sharedObj = obj;
}
#Override
public void run() {
while (true) {
this.sharedObj.get();
}
}
}
public class MainThread {
public static void main(String[] args) {
ThreadSignaling sharedObj = new ThreadSignaling();
Producer in = new Producer(sharedObj);
Consumer out = new Consumer(sharedObj);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
} enter code here
The problem with your code is that you do not have an exit condition for the Consumer. The run() method of the Consumer will run forever, and while doing repeated get calls on the shared object.
What you need to do is to make aware the Consumer that the Producer has set the stopFlag in the shared object. And if that stopFlag is true then the loop in the Consumer should also finish. There are several ways you can do that:
redefine get method to return the value of stopFlag;
define a new method to return just the value of stopFlag;
In either cases, make a test in the Consumer.run() and if the value is true, just do a return so the infinite loop ends.

Java Thread inter process communication working in boolean variable condition but not in int?

I have code to communicating 2 threads in JRE6.
When i run following program my expected output is come
like,
A: Hi
B: hi
A: How r u?
B: im fine wat about u?
A: I'm fine
B: Me too
class Chat {
boolean flag = false;
public synchronized void getTalk1(String msg) throws InterruptedException {
if (flag) {
wait();
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void getTalk2(String msg) throws InterruptedException {
if (!flag) {
wait();
}
System.out.println(msg);
flag = false;
notify();
}
}
class Thread1 extends Thread {
Chat chat;
public Thread1(Chat chat) {
this.chat = chat;
}
String[] talk = { "Hi", "How r u?", "I'm fine" };
#Override
public void run() {
for (int i = 0; i < talk.length; i++) {
try {
chat.getTalk1("A: " + talk[i]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Thread2 extends Thread {
Chat chat;
public Thread2(Chat chat) {
this.chat = chat;
}
String[] talk = { "hi", "im fine wat about u?", "Me too" };
#Override
public void run() {
for (int i = 0; i < talk.length; i++) {
try {
chat.getTalk2("B: " + talk[i]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Conversation {
public static void main(String[] args) {
Chat chat = new Chat();
new Thread1(chat).start();
new Thread2(chat).start();
}
}
But when i change Chat class flag variable boolean to int type
class Chat {
volatile int flag = 2;
public synchronized void getTalk1(String msg) throws InterruptedException {
if (flag == 1) {
wait();
}
System.out.println(msg);
flag = 2;
notify();
}
public synchronized void getTalk2(String msg) throws InterruptedException {
if (flag == 2) {
wait();
}
System.out.println(msg);
flag = 1;
notify();
}
}
The output is varied and executing not stop like
A: Hi
A: How r u?
A: I'm fine
...still running
What is the reason?
Compare
if (flag) {
wait();
}
System.out.println(msg);
flag = true;
notify();
with
if (flag == 1) {
wait();
}
System.out.println(msg);
flag = 2;
notify();
In the first case, you wait if flag == true and then set flag = true. In the second case, you wait if flag == 1 and then set flag = 2. The logic is inverted.
Just mixed values, in your case flag is always 2.
class Chat {
int flag = 2;
public synchronized void getTalk1(String msg) throws InterruptedException {
if (flag == 2) {
wait();
}
System.out.println(msg);
flag = 2;
notify();
}
public synchronized void getTalk2(String msg) throws InterruptedException {
if (flag == 1) {
wait();
}
System.out.println(msg);
flag = 1;
notify();
}
}
Your logic is incorrect when you use int instead of boolean. To make it less confusing use int flag = 0 for false and flag = 1 for true. In multi-threading it is a good practice to write conditions for wait() and notify() in a while loop instead of a if block just to make sure the value of the variable/flag is still the same after the thread wakes up.
e.g. -
class Chat {
boolean flag = false;
public synchronized void getTalk1(String msg) throws InterruptedException {
while (flag) {
wait();
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void getTalk2(String msg) throws InterruptedException {
while (!flag) {
wait();
}
System.out.println(msg);
flag = false;
notify();
}
}

Continue the execution after exception

I have these two Class :
public class TryException {
int a=0;
TryException(int c) {
a = c;
}
public boolean operation() //just example
{
if(a!=10)
{
System.out.println(a);
return true;
}else{
throw new RuntimeException("display something");
}
}
}
and the main :
public class Test {
static public void main(String args[])
{
int val =20;
TryException ex = new TryException(val);
try{
while(ex.operation()){
ex.a = --val;
}
}catch(RuntimeException e)
{
System.out.println("try exception");
}
}
}
when i run this program, the execution is stoped just when it detects the exception. How to continue the execution of the same while after exception ?
Move the try-catch inside the loop.
boolean run = true;
while(run){
ex.a = --val;
try{
run = ex.operation();
}catch(RuntimeException e){
System.out.println("try exception");
}
}
You need to decide when to set run to false...
It may help...
public class Test {
static public void main(String args[])
{
int val =20;
TryException ex = new TryException(val);
boolean status = true;
while(status){
try{
status = ex.operation();
} catch(RuntimeException e) {
status = true; //Or whatever...
}
ex.a = --val;
}
}
}

notifyAll() method is not working in my code

I am trying to implement Bully Algorithm in Java using threads.
Here is the code which I have written.
package newbully;
public class NewBully {
public static void main(String[] args) {
int total_processes = 4;
Thread1[] t = new Thread1[total_processes];
for (int i = 0; i < total_processes; i++) {
t[i] = new Thread1(new Process(i+1, i+1), total_processes);
}
try {
Election.initialElection(t);
} catch (Exception e) {
System.out.println("Possibly you are using null references in array");
}
for (int i = 0; i < total_processes; i++) {
new Thread(t[i]).start();
}
}
}
package newbully;
public class Election {
private static boolean pingFlag = false;
private static boolean electionFlag = false;
private static boolean messageFlag = false;
public static boolean isMessageFlag() {
return messageFlag;
}
public static void setMessageFlag(boolean messageFlag) {
Election.messageFlag = messageFlag;
}
public static boolean isPingFlag() {
return pingFlag;
}
public static void setPingFlag(boolean pingFlag) {
Election.pingFlag = pingFlag;
}
public static boolean isElectionFlag() {
return electionFlag;
}
public static void setElectionFlag(boolean electionFlag) {
Election.electionFlag = electionFlag;
}
public static void initialElection(Thread1[] t) {
Process temp = new Process(-1, -1);
for (int i = 0; i < t.length; i++) {
if (temp.getPriority() < t[i].getProcess().getPriority()) {
temp = t[i].getProcess();
}
}
t[temp.pid - 1].getProcess().CoOrdinatorFlag = true;
}
}
package newbully;
public class Process {
int pid;
boolean downflag,CoOrdinatorFlag;
public boolean isCoOrdinatorFlag() {
return CoOrdinatorFlag;
}
public void setCoOrdinatorFlag(boolean isCoOrdinator) {
this.CoOrdinatorFlag = isCoOrdinator;
}
int priority;
public boolean isDownflag() {
return downflag;
}
public void setDownflag(boolean downflag) {
this.downflag = downflag;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public Process() {
}
public Process(int pid, int priority) {
this.pid = pid;
this.downflag = false;
this.priority = priority;
this.CoOrdinatorFlag = false;
}
}
package newbully;
import java.util.*;
import java.io.*;
import java.net.*;
public class Thread1 implements Runnable {
private Process process;
private int total_processes;
ServerSocket[] sock;
Random r;
public Process getProcess() {
return process;
}
public void setProcess(Process process) {
this.process = process;
}
public Thread1(Process process, int total_processes) {
this.process = process;
this.total_processes = total_processes;
this.r = new Random();
this.sock = new ServerSocket[total_processes];
}
private void recovery() {
}
synchronized private void pingCoOrdinator() {
try {
if (Election.isPingFlag()) {
wait();
}
if (!Election.isElectionFlag()) {
Election.setPingFlag(true);
System.out.println("Process[" + this.process.getPid() + "]: Are you alive?");
Socket outgoing = new Socket(InetAddress.getLocalHost(), 12345);
outgoing.close();
Election.setPingFlag(false);
notifyAll();
}
} catch (Exception ex) {
//Initiate Election
System.out.println("process[" + this.process.getPid() + "]: -> Co-Ordinator is down\nInitiating Election");
Election.setElectionFlag(true);
Election.setPingFlag(false);
notifyAll();
}
}
synchronized private void executeJob() {
int temp = r.nextInt(20);
for (int i = 0; i <= temp; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Error Executing Thread:" + process.getPid());
System.out.println(e.getMessage());
}
}
}
synchronized private boolean sendMessage() {
boolean response = false;
int i = 0;
try {
if (Election.isMessageFlag()) {
wait();
}
Election.setMessageFlag(true);
for (i = this.process.getPid() + 1; i <= this.total_processes; i++) {
try {
Socket electionMessage = new Socket(InetAddress.getLocalHost(), 10000 + i);
System.out.println("Process[" + this.process.getPid() + "] -> Process[" + i + "] responded to election message successfully");
electionMessage.close();
response = true;
} catch (Exception ex) {
System.out.println("Process[" + this.process.getPid() + "] -> Process[" + i + "] did not respond to election message");
}
}
Election.setMessageFlag(false);
notifyAll();
} catch (Exception ex1) {
System.out.println(ex1.getMessage());
}
return response;
}
synchronized private void serve() {
try {
//service counter
ServerSocket s = new ServerSocket(12345);
for (int counter = 0; counter <= 10; counter++) {
Socket incoming = s.accept();
System.out.println("Process[" + this.process.getPid() + "]:Yes");
Scanner scan = new Scanner(incoming.getInputStream());
PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
if (scan.hasNextLine()) {
if (scan.nextLine().equals("Who is the co-ordinator?")) {
System.out.print("Process[" + this.process.getPid() + "]:");
out.println(this.process);
}
}
if (counter == 10) {//after serving 10 requests go down
this.process.setCoOrdinatorFlag(false);
this.process.setDownflag(true);
try {
incoming.close();
s.close();
sock[this.process.getPid() - 1].close();
Thread.sleep((this.r.nextInt(10) + 1) * 50000);//going down
recovery();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
#Override
public void run() {
try {
sock[this.process.getPid() - 1] = new ServerSocket(10000 + this.process.getPid());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
while (true) {
if (process.isCoOrdinatorFlag()) {
//serve other processes
serve();
} else {
while (true) {
//Execute some task
executeJob();
//Ping the co-ordinator
pingCoOrdinator();
if (Election.isElectionFlag()) {
if (!sendMessage()) {//elect self as co-ordinator
System.out.println("New Co-Ordinator: Process[" + this.process.getPid() + "]");
this.process.setCoOrdinatorFlag(true);
Election.setElectionFlag(false);
break;
}
}
}
}
}
}
}
When I am trying to execute the code out of the 4 threads which I have created some threads are waiting premanently using wait() call. They are not being notified by notifyAll(). Can anyone suggest why this is happening?
Each thread is calling wait() on itself (on its own Thread1 instance). That means that when you call notifyAll() on that same Thread1 instance, only the single Thread1 that is waiting it will be notified, and not all the other threads.
What you have to do is make all your Thread1 objects call wait() on a single, common object, and also call notifyAll() on that same object.
Ofcourse you have to synchronize on the common object when you call wait() or notifyAll() on it; if you don't do that, you'll get an IllegalMonitorStateException.
// Object to be used as a lock; pass this to all Thread1 instances
Object lock = new Object();
// Somewhere else in your code
synchronized (lock) {
lock.wait();
}
// Where you want to notify
synchronized (lock) {
lock.notifyAll();
}
Both notify() (or notifyAll()) and wait() must be written into synchronized block on the same monitor.
For example:
synchronized(myLock) {
wait();
}
..................
synchronized(myLock) {
notifyAll();
}

Categories