简体   繁体   中英

Thread starts running and terminates itself


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:

  1. 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 Counter s are forked but the main only sleeps a bit and then quits. The Counter threads are still running.

  2. 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) { ... 
  3. 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);}
    }
}
  1. I have made a single Counter class instead of 3 classes you are using.

  2. I made the reservation method to be synchronized.

  3. 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.

  4. 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();


  }





 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM