sky5412 2020-04-07 20:58 采纳率: 0%
浏览 273
已采纳

java实现同步多线程的问题

卖票的代码,无法实现完整的多线程,只有一两个线程会输出。
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循环中,就无法实现同步线程呢?

  • 写回答

5条回答 默认 最新

  • 毕小宝 博客专家认证 2020-04-08 07:33
    关注

    有两个问题:
    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并发编程专栏,里面有解释这类常见问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行