卖票的代码,无法实现完整的多线程,只有一两个线程会输出。
import java.util.Scanner;
class MyThread implements Runnable{
private int ticket; //票数
private String name; //线程名称
public MyThread() {
super();
}
public MyThread(int ticket,String name) {
super();
this.ticket = ticket;
this.name = name;
}
public int getTicket() {
return ticket;
}
public void setTicket(int ticket) {
this.ticket = ticket;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() { //控制线程输出
int t = this.ticket;
synchronized(this){ //同步线程
for(int i = 1;i<=t;i++) {
if(this.ticket>0) {
System.out.println(this.name+",当前余票是:"+(this.ticket-1)+".售出票号是:"+i);
}
this.ticket--;
}
}
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入总的票数:");
int ticketNum = in.nextInt();
System.out.println("请输入窗口数目:");
int num = in.nextInt();
MyThread mt = new MyThread();
for(int i = 1;i<=num;i++) {
mt.setName("售票窗口"+i+"正在售票");
mt.setTicket(ticketNum);
new Thread(mt).start();
}
}
}
以下为代码运行结果:
麻烦大佬们解答一下,谢谢!
ps:为什么在主方法的设置多线程for循环那里,将创建和实例化对象放入for循环中,就无法实现同步线程呢?
有两个问题:
1、之所以只看到一个线程的输出信息,setName 使用的是同一个 MyThread ,每次都覆盖上次的值,最后只有一个 5 的时候生效了,把 new MyThread 挪到内部。
2、同步的逻辑有问题,购票的票数应该是所有线程共享的,应该设置为静态变量,所有线程用同一个锁,保证票数一致。
调整代码如下:
import java.util.Scanner;
class MyThread implements Runnable {
private static int ticket; // 票数
private String name; // 线程名称
public MyThread() {
super();
}
public MyThread(int ticket, String name) {
super();
this.name = name;
}
public int getTicket() {
return ticket;
}
public static void setTicket(int ticket) {
MyThread.ticket = ticket;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() { // 控制线程输出
while(ticket>0) {
synchronized (MyThread.class) { // 同步线程
System.out.println(this.name + ",当前余票是:" + (ticket - 1) + ".售出票号是:" + ticket);
ticket--;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入总的票数:");
int ticketNum = in.nextInt();
System.out.println("请输入窗口数目:");
int num = in.nextInt();
MyThread.setTicket(ticketNum);
for (int i = 1; i <= num; i++) {
MyThread mt = new MyThread();
mt.setName("售票窗口" + i + "正在售票");
new Thread(mt).start();
}
in.close();
}
}
这样就就正常了,有需要可以关注我的Java并发编程专栏,里面有解释这类常见问题。
实现同步线程,用synchronized嵌套下for试试
synchronized (this) {
。。。
}
synchronized 这个关键字表示同步,你使用 synchronized表示当前只允许一个线程操作,其他线程等待操作,当第一个线程结束后,开始第二个
悲观锁。具有排它锁。
你好,创建实例化对象放在for循环中不能实现同步线程。若创建的对象放在里面,则意思完全不一样,是对不同的对象进行线程操作,而多线程是要对同一个对象进行操作
增加票数,每买一张票睡眠1s,这样能让线程卖票数变得更加分散