更新:谢谢大家!我根据建议修改了程序,下面给出的代码是修改后的代码。
原帖: 我已经完成了一些“应用和分析”类型的问题,在一个问题中,程序员被要求在电影院的三个预订柜台应用多线程概念,并计算一个节目中收集的预订总数和金额。 / 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方法中的输入,它也不会要求输入。
答案 0 :(得分:5)
我可以很好地编译它,但是当我运行程序时,这就是我得到的......
您的计划存在一些问题:
主线程在打印出总计之前没有等待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
个帖子仍在运行。
每个Counter
个主题都在向Cinema
内的字段添加值,但Cinema
中没有同步。无论何时两个线程正在修改同一个字段,都必须有一些互斥保护和内存同步。
这里最简单的方法是将Cinema.reservation(...)
方法设为synchronized
。然后,每个Counter
对象都会锁定Cinema
实例,这将确保只有一个Counter
一次更新Cinema
。 synchronized
关键字还可确保Cinema
对象中的字段也与内存同步。
synchronized void reservation(int n,int p) { ...
与往常一样,您应该考虑使用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);}
}
}
我制作了一个Counter类而不是你正在使用的3个类。
我使预订方法同步。
我在所有三个线程上调用了join方法。所以程序不会突然终止。最后一个会被终止的主线是主要的。
在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();
}
}