I am trying to understand producer and consumer program but when I create the object thread1 in main function the thread suspends (mainHumpty Dumpty sat on a wall) why is this happened?
import java.util.Random;
public class Main {
public static void main(String[] args) {
Message mes = new Message();
Writer t1 = new Writer(mes);
t1.start();
while(true)
{
t1.run();
}
}
}
class Message {
private String message;
private boolean empty = true;
public synchronized String read() {
while(empty) {
try{
wait();
}
catch(InterruptedException e)
{
}
}
empty = true;
notifyAll();
return message;
}
public synchronized void write(String message) {
while(!empty) {
try{
wait();
}
catch(InterruptedException e)
{
}
}
empty = false;
notifyAll();
this.message = message;
}
}
class Writer extends Thread {
private Message message;
public Writer(Message message) {
this.message = message;
}
public void run() {
String messages[] = {
"Humpty Dumpty sat on a wall",
"Humpty Dumpty had a great fall",
"All the king's horses and all the king's men",
"Couldn't put Humpty together again"
};
Random random = new Random();
for(int i=0; i<messages.length; i++) {
message.write(messages[i]);
System.out.println(Thread.currentThread().getName() + messages[i]);
try {
Thread.sleep(random.nextInt(2000));
} catch(InterruptedException e) {
}
}
message.write("Finished");`
I expected to print infinitely all the members of the array and the name of the thread which I created but the only that is printed is the first string and the main thread
Related
I have to create a program that simulate a bomb... The user has 5 seconds to digit the right code, if he can't, the bomb explodes.
class Codice implements Runnable{
String code;
#Override
public void run() {
code = JOptionPane.showInputDialog("Inserire codice disinnesco:");
if(code.equals(Bomba.check)) {
Bomba.s = "true";
JOptionPane.showMessageDialog(null, "Bomba disinnescata");
}
System.out.println(Bomba.s);
}
}
class Esplosione implements Runnable{
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!Bomba.s.equals("true")) {
JOptionPane.showMessageDialog(null, "BOOM!");
}
}
}
public class Bomba {
static String s = "false";
static String check = "123456";
public static void main(String[] args) throws IOException {
Codice c = new Codice();
Esplosione ex = new Esplosione();
Thread t1 = new Thread(c);
Thread t2 = new Thread(ex);
t1.start();
t2.start();
}
}
With this code i can insert the code, and if it's right the bomb doesn't explodes and the program finish. If 5 seconds passes, the message "boom" appears but the first thread doeasn't stop... How can i do?
There are many ways to coordinate between threads; interrupting is one way. Here is an example using Thread.interrupt. It dispenses with your state variable s, which becomes unnecessary:
import javax.swing.*;
import java.io.*;
class Codice implements Runnable {
String code;
Thread other;
Codice(Thread other) {
this.other = other;
}
#Override
public void run() {
code = JOptionPane.showInputDialog("Inserire codice disinnesco:");
if(code.equals(Bomba.check)) {
other.interrupt();
JOptionPane.showMessageDialog(null, "Bomba disinnescata");
}
}
}
class Esplosione implements Runnable {
#Override
public void run() {
try {
Thread.sleep(5000);
JOptionPane.showMessageDialog(null, "BOOM!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Bomba {
static String check = "123456";
public static void main(String[] args) throws IOException {
Esplosione ex = new Esplosione();
Thread t2 = new Thread(ex);
Codice c = new Codice(t2);
Thread t1 = new Thread(c);
t1.start();
t2.start();
}
}
I have a simple code, consisting of 4 threads (2 modify the data and 2 read the data). I just wrote this sample code to play around with Semaphor and I am not sure why I get ava.base/java.util.ArrayList$Itr.checkForComodification exception? Here are the source code and thanks for any insights.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static class InnerWriterSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerWriterSemaphoreThread(List<String> list, Semaphore w) {
fList = list;
fWriteSem = w;
}
private void prune() {
System.out.println(Thread.currentThread().getName()+" in prune()..");
for (String s : fList) {
fList.remove(s);
}
}
#Override
public void run() {
String name = Thread.currentThread().getName();
String text;
while (true) {
text = RandomTextGenerator.getRandomSNumbertring();
try {
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphore to write..");
Thread.sleep(0L,4);
}
if (fList.size() > 10) {
prune();
}
fList.add(text);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
fWriteSem.release();// notify readers that write has completed
System.out.println(name+" finished writing, releasing semaphore..");
}
}//while()
}//run()
}//WriterSemaphoreThread
public static class InnerReaderSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerReaderSemaphoreThread(List<String> list,Semaphore w) {
fList = list;
fWriteSem = w;
}
private void sleep(){
try{
Thread.sleep(0L, 4);
}catch(InterruptedException e){
e.printStackTrace();
}
}
#Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name + " in run()..");
try {
while(fList.isEmpty()){
System.out.println(name+" list is empty, going to sleep..");
sleep();
}
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphor to read..");
Thread.sleep(0l,4);
}
for (String text : fList) {
System.out.println(name + " reading from list " + text);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
finally{
fWriteSem.release(); //Notify threads who want to write to the list
System.out.println(name+" finished reading, releasing semaphore and going to sleep..");
sleep();
}
}
}
}//ReaderSemaphoreThread
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Semaphore r = new Semaphore(1);
Thread th1 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 1");
Thread th2 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 2");
Thread th3 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 3");
Thread th4 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 4");
th2.start();
th4.start();
th1.start();
th3.start();
}
}
Above is the sample source code
As #assylias mentioned in comment it happens when you remove elements from list in foreach loop. Just replace
for (String s : fList) {
fList.remove(s);
}
with
fList.clear();
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.
According to wikipedia: "The race conditions that cause spurious wakeups should be considered rare".
But when I run this code, it is showing me that spurious wakeup happens quite often.
Is this actually spurious wakeup or there's just a sneaky race condition in my code?
import java.util.Random;
public class Main {
public static void main(String[] args) throws Exception {
// Message message = new SafeMessage();
Message message = new SpuriousMessage();
String[] producerNames = { "p01", "p02", "p03", "p04", "p05", "p06", "p07", "p08", "p09" };
for (String producerName : producerNames) {
Producer producer = new Producer(producerName, message);
new Thread(producer).start();
}
String[] consumerNames = { "c-01", "c-02", "c-03", "c-04" };
for (String consumerName : consumerNames) {
Consumer consumer = new Consumer(consumerName, message);
new Thread(consumer).start();
}
}
}
abstract class Message {
protected String message;
protected boolean empty = true;
public abstract String getMessage() throws InterruptedException;
public abstract void setMessage(String message) throws InterruptedException;
protected static String avoidNull(String obj) {
return obj != null ? obj : "Default message";
}
}
class SpuriousMessage extends Message {
#Override
public synchronized String getMessage() throws InterruptedException {
wait();
empty = true;
String temp = message;
message = "---------------------------------------- Spurious wakeup";
return temp;
}
#Override
public synchronized void setMessage(String message) throws InterruptedException {
this.message = avoidNull(message);
this.empty = false;
notifyAll();
}
}
class SafeMessage extends Message {
#Override
public synchronized String getMessage() throws InterruptedException {
while (empty) {
wait();
}
empty = true;
notifyAll();
String temp = message;
message = "---------------------------------------- Spurious wakeup";
return temp;
}
#Override
public synchronized void setMessage(String message) throws InterruptedException {
while (!empty) {
wait();
}
this.message = avoidNull(message);
this.empty = false;
notifyAll();
}
}
class Producer implements Runnable {
private static final Random RANDOM = new Random();
private String producerName = "Default";
private Message message;
public Producer(String producerName, Message message) {
this.producerName = producerName;
this.message = message;
}
#Override
public void run() {
while (true) {
try {
message.setMessage(producerName + " :: " + randomMessage());
rest(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static String randomMessage() {
final String[] messageArray = { "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot",
"Golf", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", "November", "Oscar",
"Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey",
"Xray", "Yankee", "Zulu" };
return messageArray[RANDOM.nextInt(messageArray.length)];
}
private void rest(long millis) {
try {
Thread.sleep(millis);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private final long TIMEOUT = 5;
private String consumerName = "Default";
private Message message;
public Consumer(String consumerName, Message message) {
this.consumerName = consumerName;
this.message = message;
}
#Override
public void run() {
while (true) {
try {
System.out.println(consumerName + " :: " + message.getMessage());
rest(TIMEOUT);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void rest(long millis) {
try {
Thread.sleep(millis);
} catch (Exception e) {
e.printStackTrace();
}
}
}
When a spurious wakeup happens, wait() exits although notify/notifyAll has not been called. In your case you call notifyAll from the producer so it is normal that wait exits...
To observe a spurious wakeup, you would need to run your Consumers only. If they print the "spurious wakeup" message then that will be a real spurious wakeup because it won't be caused by notify/All any more. However it may never happen.
See also: Do spurious wakeups actually happen?.
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();
}