Thread starts running and terminates itself - java

Update : Thanks everyone! I've modified the program as per the suggestions and the code given below is the modified code.
Original Post :
I've gone through some "Apply and Analyze" type of questions and in one question, the programmer has been asked to apply multithreading concept for three reservation counters of a cinema theater and calculate the total booking numbers and amount collected in a show.
And I've written a program for the same which you can see below:
import java.io.*;
import java.lang.*;
class Cinema
{
int no=0,price=0;
synchronized void reservation(int n,int p)
{
no=no+n;
price=price+p;
}
}
class Counter implements Runnable
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
Cinema c;
int not,cost;
Counter(Cinema c)
{
this.c=c;
}
public void run()
{
try
{
System.out.print("\nCounter 1");
System.out.print("\nEnter the no. of tickets :");
not=Integer.parseInt(br.readLine());
cost=not*150;
c.reservation(not,cost);
}
catch(IOException e){System.out.print("\n"+e);}
}
}
class CinemaMain
{
public static void main(String args[])throws IOException
{
Cinema c=new Cinema();
System.out.print("\nCounter 1");
Thread c1=new Thread(new Counter(c));
c1.start();
c1.join();
System.out.print("\nCounter 2");
Thread c2=new Thread(new Counter(c));
c2.start();
c2.join();
System.out.print("\nCounter 3");
Thread c3=new Thread(new Counter(c));
c3.start();
c3.join();
try
{
Thread.sleep(500);
}
catch(InterruptedException ie)
{
System.out.print("\n"+ie);
}
System.out.print("\nTotal no. of tickets :"+c.no);
System.out.print("\nTotal Money collected:"+c.price);
}
}
I can compile it just fine, but when I run the program, this is what I get -->LINK (since I don't have 10 reputation, I couldn't post the image here, sorry!) I don't know why, it doesn't ask for input even though I've written the code to get input in the run method.

I can compile it just fine, but when I run the program, this is what I get ...
There are a couple of things wrong with your program:
The main thread is not waiting for the Counter threads to finish before it prints out the totals. If you need to wait for a thread to complete then you call thread.join() on it.
Thread counter1 = new Thread(new Counter1(c));
counter1.start();
// start other threads here...
// now wait for the counter1 to finish
counter1.join();
In your case, the 3 Counters are forked but the main only sleeps a bit and then quits. The Counter threads are still running.
Each of the Counter threads is adding values to fields inside the Cinema but there is no synchronization in Cinema. Anytime two threads are modifying the same field, there must be some mutex protection and memory synchronization.
The easy thing to do here is to make the Cinema.reservation(...) method be synchronized. Then each of the Counter objects will get a lock on the Cinema instance which will ensure only one Counter updates the Cinema at one time. The synchronized keyword also ensures that the fields in the Cinema object are memory synchronized as well.
synchronized void reservation(int n,int p) { ...
As always, you should consider using the ExecutorService classes instead of forking threads yourself. See the Java tutorial.

Try this Approach ;
import java.io.*;
import java.lang.*;
public class Cinema
{
int no=0,price=0;
synchronized void reservation(int n,int p)
{
no=no+n;
price=price+p;
}
public static void main(String args[])throws IOException, InterruptedException
{
Cinema c=new Cinema();
Thread t1 = new Thread(new Counter(c,"Counter 1"));
t1.start();
Thread t2 = new Thread(new Counter(c,"Counter 2"));
t2.start();
Thread t3 = new Thread(new Counter(c,"Counter 3"));
t3.start();
t1.join();
t2.join();
t3.join();
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
System.out.print("\n"+ie);
}
System.out.print("\nTotal no. of tickets :"+c.no);
System.out.print("\nTotal Money collected:"+c.price);
}
}
class Counter implements Runnable
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
Cinema c;
int not,cost;
String counterName;
Counter(Cinema c,String counterName)
{
this.c=c;
this.counterName=counterName;
}
public void run()
{
try
{
synchronized(c) {
System.out.print("\n" + counterName);
System.out.print("\nEnter the no. of tickets :");
not=Integer.parseInt(br.readLine());
cost=not*150;
c.reservation(not,cost);
}
}
catch(IOException e){System.out.print("\n"+e);}
}
}
I have made a single Counter class instead of 3 classes you are using.
I made the reservation method to be synchronized.
I called join method on all the three threads. So the program will not terminate abruptly.TGhe last thread that would teminate would be main.
In run() method , I locked the Cinema object c. This will resolve your issue of Buffered Reader at this moment of time. But in real world scenario different threads will be run by different people. So no need to lock the Cinema object there.it is just for your usage.

Why do you need to make threads when you can just make it way simpler?
import java.io.*;
import java.lang.*;
import java.util.Scanner;
public class Cinema {
public Cinema(){
int no=0,price=0;
}
public int Count () {
int not,not2, not3, cost,cost2,cost3;
System.out.print("\nCounter 1");
System.out.print("\nEnter the no. of tickets: ");
Scanner br=new Scanner(System.in);
String input=br.nextLine();
not=Integer.parseInt(input);
cost=not*150;
System.out.println("Cost of tickets: "+cost);
System.out.print("\nCounter 2");
System.out.print("\nEnter the no. of tickets: ");
Scanner br2=new Scanner(System.in);
String input2=br2.nextLine();
not2=Integer.parseInt(input2);
cost2=not2*150;
System.out.println("Cost of tickets: "+cost2);
System.out.print("\nCounter 3");
System.out.print("\nEnter the no. of tickets: ");
Scanner br3=new Scanner(System.in);
String input3=br3.nextLine();
not3=Integer.parseInt(input3);
cost3=not3*150;
System.out.println("Cost of tickets: "+cost3);
int total=cost+cost2+cost3;
int tickets=not+not2+not3;
System.out.println("Total price for tickets is: "+total);
System.out.println("Total number of tickets is: "+tickets);
return total;
}
public static void main(String args[])
{
Cinema c=new Cinema();
c.Count();
}
}

Related

Make two methods run one after another in thread while using synchronization

I have written a demo code for Atm machine while using synchronization
class Atm{
synchronized void checkBalance(String str){
System.out.print(str+" is checking his ");
try{Thread.sleep(1000);}catch(Exception e){
System.out.println(e);
}
System.out.println("Balance ");
}
synchronized void withdraw(String str, int amt){
System.out.print(str+ " is withdrawing amount: ");
try{Thread.sleep(1000);}catch(Exception e){
System.out.println(e);
}
System.out.println(amt);
}
}
class Customer extends Thread{
String name;
int amt;
Atm a;
Customer (Atm a){
this.a=a;
}
public void useAtm(){
a.checkBalance(name);
a.withdraw(name,amt);
}
public void run(){
useAtm();
}
}
after running the main method i get the output as Output where as soon as the thread 1 after releasing checkBalance, goes to withdraw method but thread 2 gets access to check balance before thread 1 could get monitor on withdraw and i get the output as such.
But on other cases i get the output as: Output 2 in order... where the threads access the methods one after another. How can i make sure that thread 2 or any other thread doesn't access checkBalance till thread 1 has completed accessing both checkBalance and withdraw?
Basically how to make the output as "Ram checks, Ram withdraws, S checks, S withdraws...." instead of "R checks, S checks, S withdraws, R withdraws"
Main:
public class Main {
public static void main(String[] args) {
// write your code here
Atm a=new Atm();
Customer c1=new Customer(a);
Customer c2=new Customer(a);
Customer c3=new Customer(a);
c1.name="Ram";
c1.amt=5000;
c2.name="Hari";
c2.amt=51000;
c3.name="Shyam";
c3.amt=545000;
Customer c4=new Customer(a);
Customer c5=new Customer(a);
Customer c6=new Customer(a);
c4.name="xam";
c4.amt=500220;
c5.name="pari";
c5.amt=5100220;
c6.name="ohyam";
c6.amt=54501200;
c1.start();
c2.start();
c3.start();
c4.start();
c5.start();
c6.start();
}
}
Here you did try to synchronize functions individually, which make sense if you want to use them separately synchronized. But when you want two functions to run in a synchronized way try using
public void useAtm(){
synchronized(a){
a.checkBalance(name);
a.withdraw(name,amt);
}
}
which will solve your problem. Try removing synchronized tag to methods.
void checkBalance(String str){
void withdraw(String str, int amt){
I hope it solved your issue.

Print alternately with three threads [duplicate]

I am trying to print numbers from 1 to 10 using three threads. thread 1 prints 1, 2 prints 2, 3 prints 3, 4 is printed by thread 1 again and so on.
I have created a shared printer resource that helps those threads to print number. But I am getting confused as how can i make the number to be visible by all threads.
The problem is eachthread is seeing their own copy of number while I need the same number to be shared by all threads.
I am trying to create this example for learning purposes. I have seen other pages on SO that had same kind of problem but I am not able to get the concept.
Any help is appreciated.
how is this example diffrent from what I am doing?
Printing Even and Odd using two Threads in Java
public class PrintAlternateNumber {
public static void main(String args[]) {
SharedPrinter printer = new SharedPrinter();
Thread t1 = new Thread(new myRunnable2(printer,10,1),"1");
Thread t2 = new Thread(new myRunnable2(printer,10,2),"2");
Thread t3 = new Thread(new myRunnable2(printer,10,3),"3");
t1.start();
t2.start();
t3.start();
}
}
class myRunnable2 implements Runnable {
int max;
SharedPrinter printer;
int threadNumber;
int number=1;
myRunnable2(SharedPrinter printer,int max,int threadNumber) {
this.max=max;
this.printer=printer;
this.threadNumber=threadNumber;
}
#Override
public void run() {
System.out.println(" The thread that just entered run "+ Thread.currentThread().getName());
for(int i =1;i<max;i++){
try {
printer.print(i,threadNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SharedPrinter {
boolean canPrintFlag=false;
public synchronized void print(int number,int threadNumber) throws InterruptedException{
if(number%3==threadNumber) {
canPrintFlag=true;
}
while(!canPrintFlag)
{
System.out.println(Thread.currentThread().getName() + " is waiting as it cannot print " + number);
wait();
}
System.out.println(Thread.currentThread().getName()+" printed "+number);
canPrintFlag=false;
notifyAll();
}
}
//output
//The thread that just entered run 2
// The thread that just entered run 3
//The thread that just entered run 1
//3 is waiting as it cannot print 1
//1 printed 1
//1 is waiting as it cannot print 2
//3 is waiting as it cannot print 1
//2 is waiting as it cannot print 1
Technique second
it is still incomplete but I am close
output
0printed by0
2printed by2
1printed by1
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class AlternateNumber {
public static void main(String args[]) {
printerHell ph = new printerHell();
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);
for(int i=0;i<10;i++)
{
queue.add(i);
}
Thread t1 = new Thread(new myRunnableHell(queue,0,ph),"0");
Thread t2 = new Thread(new myRunnableHell(queue,1,ph),"1");
Thread t3 = new Thread(new myRunnableHell(queue,2,ph),"2");
t1.start();
t2.start();
t3.start();
}
}
class myRunnableHell implements Runnable {
BlockingQueue<Integer> queue;
int threadNumber;
printerHell ph;
myRunnableHell(BlockingQueue<Integer> queue, int threadNumber,printerHell ph) {
this.queue=queue;
this.threadNumber=threadNumber;
this.ph=ph;
};
int currentNumber;
#Override
public void run() {
for(int i=0;i<queue.size();i++)
{
currentNumber=queue.remove();
if(threadNumber%3==currentNumber)
{
ph.print(currentNumber);
}
}
}
}
class printerHell {
public synchronized void print(int Number)
{
System.out.println(Number + "printed by" + Thread.currentThread().getName());
}
}
Please see my solution here..
Using simple wait/notify
https://stackoverflow.com/a/31668619/1044396
Using cyclic barriers:
https://stackoverflow.com/a/23752952/1044396
For your query on 'How different it is from even/odd thread problem.
--> it is almost same ... instead of maintaining two states have one more state to call the third thread, so I believe,this can be extended any number of threads.
EDIT:
You may view this approach when you want to have 'n' number of threads to do the work sequentially.(Instead of having different classes t1,t2,t3 etc)
https://codereview.stackexchange.com/a/98305/78940
EDIT2:
Copying the code here again for the above solution
I tried to solve using a single class 'Thrd' which gets initialized with its starting number.
ThreadConfig class which as size of total number of threads you want to create.
State class which maintains the state of the previous thread.(to maintain ordering)
Here you go..(please review and let me know your views)
EDIT:
How it works -->
when a thread Tx gets a chance to execute.. it will set state variable's state with x. So a next thread(Tx+1) waiting , will get a chance once state gets updated. This way you can maintain the ordering of threads.
I hope i am able to explain the code. Please run it and see or let me know for any specific queries on the below code
1)
package com.kalyan.concurrency;
public class ThreadConfig {
public static final int size = 5;
}
2) package com.kalyan.concurrency;
public class State {
private volatile int state ;
public State() {
this.state =3;
}
public State(int state) {
this.state = state;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
3) package com.kalyan.concurrency;
public class Thrd implements Runnable {
int i ;
int name;
int prevThread;
State s;
public Thrd(int i,State s) {
this.i=i;
this.name=i;
this.prevThread=i-1;
if(prevThread == 0) prevThread=ThreadConfig.size;
this.s=s;
}
#Override
public void run() {
while(i<50)
{
synchronized(s)
{
while(s.getState() != prevThread)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==prevThread)
System.out.println("t"+ name+ i);
s.setState(name);
i = i +ThreadConfig.size ;
s.notifyAll();
}
}
}
}
4)
package com.kalyan.concurrency;
public class T1t2t3 {
public static void main(String[] args) {
State s = new State(ThreadConfig.size);
for(int i=1;i<=ThreadConfig.size;i++)
{
Thread T = new Thread(new Thrd(i,s));
T.start();
}
}
}
OUTPUT:
t11
t22
t33
t44
t55
t16
t27
t38
t49
t510
t111
t212
t313
t414
t515
t116..............
I hope I understood you right, but there are to main "features" in java to make a variable being shared between threads:
the volatile keyword
volatile int number = 1;
AtomicInteger (a standard java class -> no library)
AtomicInteger number = new AtomicInteger(1);
These two techniques should both do what you want, however I have no experience using it, I just came upon this word, didn't know what it means and did some digging.
Some stuff to read: ;)
volatile for java explained --> http://java.dzone.com/articles/java-volatile-keyword-0
a better explanation (with IMAGES!!) but for c# (which is still the same usage) --> http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
And a link to some usages of AtomicInteger --> https://stackoverflow.com/a/4818753/4986655
I hope I could help you or at least send you in the right direction :)
- superfuzzy

Calling variables from other class

import java.util.Scanner;
public class ThreadClass{
public static void main(String[] args)
{
System.out.println("Enter the characters, Press Enter to begin");
System.out.println("The quick brown fox jumps over the lazy dog");
Scanner sc=new Scanner(System.in);
String scr= sc.nextLine();
MyThread tr=new MyThread();
try {
tr.sleep(11000);
System.out.println("Time Over");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MyThread extends Thread{
public void run()
{
System.out.println("Time over");
ThreadClass tc=new ThreadClass();
String str=tc.scr;
if(str.equals("The quick brown fox jumps over the lazy dog"))
{
System.out.println("Successfully completed");
}
else
{
System.out.println("The typed Words do not match");
}
}
}
I am trying to make an application that prompts the user to type a string within 11 seconds. To accomplish this I have two classes namely ThreadClass and MyThread. In Thread class I have defined methods to take input from the user and to set the timer to 10 seconds. In MyThread class I have defined methods for post thread completion i.e. what the program will do after the time is over. I want to add a feature in MyThread class so that it compares the user input with the string provided. The problem is that when I try to access the String variable scr, defined in ThreadClass from MyThread class by creating an it gives me an error. Even if I try to extend ThreadClass from MyThread class it gives me an error. Also declaring scr as static gives me the same result. Is there any possible way to use scr variable in MyThread?
I had while ago same issue, i used Concurrency API from java, and it works without problem
here is solution for your problem
public class ThreadClass {
public static void main(String[] args) {
final ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
System.out
.println("Enter the characters, Press Enter to begin");
System.out
.println("The quick brown fox jumps over the lazy dog");
Scanner sc = new Scanner(System.in);
return sc.nextLine();
}
});
try {
String str = future.get(11, TimeUnit.SECONDS);
System.out.println("Your string " + str);
} catch (TimeoutException | InterruptedException | ExecutionException e) {
future.cancel(true);
System.out.println("Time Over");
}
}
}
You didn't tell us what the error message is, but I can guess.
ThreadClass tc=new ThreadClass();
String str=tc.scr;
There is no instance variable named scr in your ThreadClass class. There is only a local variable with that name in your main() routine.
If you do not yet understand the difference between local variables, instance variables (a.k.a., "fields") and class variables (a.k.a., "static variables"), then it might be a little bit early for you to be trying to understand threads.

A simple wait() & notify() example - doesn't work

I tries to write a simple example that demonstrates a remote controller opertation.
The input is being accepted via the console, and a message is being printed accordingly.
Both threads run infinite loops: the main thread waits for notification, while the other waits for a console input.
I'd like to know how to fix it. The problem is that the notify doesn't stop the waiting: in other words, the words "before wait" are printed, but the words "after wait" are not. BTW, without the while(true) loops it works fine (for one button press).
Many thanks
public class MainTV {
public static int lastRemoteCode = 0;
public static void main(String[] args){
RemoteControllerThread remote = new RemoteControllerThread();
remote.start();
synchronized(remote){
while(true){
try {
System.out.println("before wait");
remote.wait();
System.out.println("after wait");
switch (lastRemoteCode){ //we use switch because there are many code options
case 0:
System.out.println("Error with remote button reading");
break;
case 3:
System.out.println("Volume Down button was pressed now!");
break;
case 4:
System.out.println("Volume Up button was pressed now!");
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
and the second class (simulates the remote controller):
import java.util.Scanner;
public class RemoteControllerThread extends Thread{
public void run(){
synchronized(this){
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
}
}
}
Both threads synchronize on the same object, this refers to the same object as remote and since both this synchronize blocks have infinite loops inside, this creates a problem. One of the thread will wait for the other one to finish, which never happens (because of the infinite loops).
To fix this, you should synchronize only the code that needs to be synchronized, like the wait() and notify() calls.
I think there are two problems with your code.
When the main thread execution reaches synchronized(remote) it might not continue because the remote controller thread (possibly) already locked the remote object. Move remote.start() into synchronized(remote) block.
In order to let execution continue from wait you need to release the object lock after notify. Change syncronization block in thread like:
-
public void run() {
Scanner in = new Scanner(System.in);
while(true){
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
synchronized(this) {
notify();
}
System.out.println("after notify");
}
}
To quote from notify() JavaDoc:
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object
Your remote never lets go of the lock. If you switch the synchronized with the while, you have a slim chance, but usually you remote will get the lock back immediately. The following works, for instance:
class RemoteControllerThread extends Thread {
public void run() {
while (true) {
synchronized (this) {
Scanner in = new Scanner(System.in);
System.out.println("Press a button in the remote please...");
int code = in.nextInt();
MainTV.lastRemoteCode = code;
System.out.println("before notify");
notify();
System.out.println("after notify");
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

How to synchronize this model correctly?

Imagine there is a masseur and he has his own salon. He is sleeping the whole day until a customer enters the salon and wakes him up.
The customer is sleeping while he gets his massage. When the masseur finishes he wakes up the customer and gets paid for his service.
The customer leaves the salon.
The masseur enters the waiting room to look for another waiting (sleeping) customer. If there aren't any the masseur goes to bed again.
This is an interesting situation when working with threads.
public class Aufg1{
public static void main(String args[]){
MassageSalon ms = new MassageSalon();
Customer c = new Customer(ms);
Masseur m = new Masseur(ms);
m.start(); c.start();
}
}
Masseur.java
public class Masseur extends Thread{
final MassageSalon salon;
public Masseur(MassageSalon pSalon){
salon = pSalon;
}
public void run(){
while(true){
salon.getNextCustomer();
salon.finishedMassage();
}
}
}
and Customer.java:
public class Customer extends Thread{
final MassageSalon salon;
public Customer(MassageSalon pSalon){
salon = pSalon;
}
public void run(){
while(true){
salon.getMassage();
}
}
}
I have a class MassageSalon. The code describes pretty much the same I just mentioned.
Now I want to use wait(), notify(), notifyAll() to ensure that everything works just like I mentioned it. I already edited the MassageSalon class and added wait(), notify() methods.
Do you think the positions for wait() and notify() are correct? When running this code the finishedMassage method isn't called. Why?
public class MassageSalon {
private int customerOnCouch = 0;
private int customerPaid = 0;
private int masseurAvailable = 0;
private int masseurBusy = 0;
private int masseurDone = 0;
private int masseurClose = 0;
public synchronized void getNextCustomer() {
while(masseurAvailable != masseurClose){
try{
System.out.println("waiting for masseur...");
wait();
}catch(InterruptedException e){
System.out.println(e);
}
}
//masseur is available to handle a new customer
System.out.println("masseur is available to handle a new customer");
masseurAvailable++;
while(customerOnCouch == customerPaid){
try{
System.out.println("waiting for customer...");
wait();
}catch(InterruptedException e){
System.out.println(e);
}
}
//and is busy as soon as a new customers takes his couch
System.out.println("and is busy as soon as a new customers takes his couch");
masseurBusy++;
}
public synchronized void finishedMassage() {
//eventually the masseur finishes the massage
System.out.println("eventually the masseur finishes the massage");
masseurDone++;
notify();
//and closes the deal as soon as the customer paid
System.out.println("and closes the deal as soon as the customer paid");
masseurClose++;
}
public synchronized void getMassage() {
//customer takes a couch
System.out.println("customer takes a couch");
customerOnCouch++;
notify();
while(masseurBusy != masseurDone){
try{
System.out.println("waiting to finish massage");
wait();
}catch(InterruptedException e){
System.out.println(e);
}
}
//and pays for the massage after it
System.out.println("and pays for the massage after it");
customerPaid++;
}
}
You're describing Dijkstra's Sleeping-Barber problem, but with a massage salon instead of a barber shop. The solution remains the same, though, and can be found here: http://en.wikipedia.org/wiki/Sleeping_barber_problem#Solution
You could use a fair Semaphore called NotSleeping.
As long as the customer does not enter the saloon, it holds NotSleeping. When customer comes in, it releases the semaphore, which wakes the thread of the masseur trying to grab NotSleeping too. After release, customer tries to hold NotSleeping again during the massage.
When done, Masseur releases NotSleeping, which is grabed again by the customer. Masseur, tries to hold NotSleeping again, until customer comes in. Etc Etc...

Categories