线程开始运行并终止自身

时间:2013-12-05 18:11:52

标签: java multithreading


更新:谢谢大家!我根据建议修改了程序,下面给出的代码是修改后的代码。


原帖: 我已经完成了一些“应用和分析”类型的问题,在一个问题中,程序员被要求在电影院的三个预订柜台应用多线程概念,并计算一个节目中收集的预订总数和金额。 / p>

我已经编写了一个相同的程序,你可以在下面看到:

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);
    }
}

我可以很好地编译它,但是当我运行程序时,这就是我得到的 - > LINK(因为我没有10个声誉,我无法在此处发布图像,对不起!)我不知道为什么,即使我已经编写了代码来获取run方法中的输入,它也不会要求输入。

3 个答案:

答案 0 :(得分:5)

  

我可以很好地编译它,但是当我运行程序时,这就是我得到的......

您的计划存在一些问题:

  1. 主线程在打印出总计之前没有等待Counter个线程完成。如果您需要等待线程完成,那么请在其上调用thread.join()

    Thread counter1 = new Thread(new Counter1(c));
    counter1.start();
    // start other threads here...
    // now wait for the counter1 to finish
    counter1.join();
    

    在你的情况下,3 Counter是分叉但主要只睡了一点然后退出。 Counter个帖子仍在运行。

  2. 每个Counter个主题都在向Cinema内的字段添加值,但Cinema中没有同步。无论何时两个线程正在修改同一个字段,都必须有一些互斥保护和内存同步。

    这里最简单的方法是将Cinema.reservation(...)方法设为synchronized。然后,每个Counter对象都会锁定Cinema实例,这将确保只有一个Counter一次更新Cinemasynchronized关键字还可确保Cinema对象中的字段也与内存同步。

    synchronized void reservation(int n,int p) { ...
    
  3. 与往常一样,您应该考虑使用ExecutorService类而不是自己分叉线程。请参阅Java tutorial

答案 1 :(得分:1)

尝试这种方法;

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. 我制作了一个Counter类而不是你正在使用的3个类。

  2. 我使预订方法同步。

  3. 我在所有三个线程上调用了join方法。所以程序不会突然终止。最后一个会被终止的主线是主要的。

  4. 在run()方法中,我锁定了Cinema对象c。这将在此时解决您的缓冲读卡器问题。但在现实世界中,不同的线程将由不同的人运行。因此无需在那里锁定Cinema对象。这仅供您使用。

答案 2 :(得分:0)

为什么你需要制作线程才能让它更简单?

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


  }





 }