weixin_43415461
CherryOto
采纳率33.3%
2021-02-25 02:00

关于线程一个小模块中的问题

现有一百个快递待派发,定义快递类Expresses 作为公共资源类,定义快递员线程类Mailman ,请开启三个线程派发此100个快递,并打印哪个快递员派发了哪一个快递。

public class Expresses {
    private String name;

    public Expresses() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Expresses(String name) {
        this.name = name;
    }

}
public class Mailman extends Thread{

    private static Expresses[] ex = new Expresses[100];
    static {
        for (int i = 0; i < 100; i++) {
            // 给100个快递赋予 名称
            ex[i] = new Expresses("快递-->"+i);
        }
    }

    private int index;
    private int number;

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            synchronized (Mailman.class) {
                if (index < 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //遍历得到对象数组每一个对象
                    Expresses e = ex[index++];
                    // 输入那个线程(快递员)派发了哪一份快递
                    System.out.println(Thread.currentThread().getName()+"派送了"+e.getName()+"快递");
                    number++;
                }
            }
        }
        System.out.println(getName() + "发了" + number+"份快递");
    }

}
    public static void main(String[] args) {
        Mailman m1 = new Mailman();
        m1.start();
        Mailman m2 = new Mailman();
        m2.start();
        Mailman m3 = new Mailman();
        m3.start();

    }
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

5条回答

  • hunger_wang hunger_wang 2月前

    无锁的实现。

    public class ExpressMail {
           private static class Expresses {
                private String name;
             
                public Expresses() {
                }
             
                public String getName() {
                    return name;
                }
             
                public void setName(String name) {
                    this.name = name;
                }
             
                public Expresses(String name) {
                    this.name = name;
                }
             
            }
            
            private static class Mailman extends Thread{
                
    //            private static volatile int curr = 0;
                private static AtomicInteger curr = new AtomicInteger(-1);
                private static Expresses[] ex = new Expresses[100];
                static {
                    for (int i = 0; i < 100; i++) {
                        // 给100个快递赋予 名称
                        ex[i] = new Expresses("快递-->"+i);
                    }
                }
             
                private int cindex = 0;
                private int number;
             
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        if ((cindex = curr.incrementAndGet()) < 100) {
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //遍历得到对象数组每一个对象
                            Expresses e = ex[cindex];
                            // 输入那个线程(快递员)派发了哪一份快递
                            System.out.println(Thread.currentThread().getName()+"派送了"+e.getName()+"快递");
                            number++;
                        }
                    }
                    System.out.println(getName() + "发了" + number+"份快递");
                }
             
            }
            
            public static void main(String[] args) {
                Mailman m1 = new Mailman();
                m1.start();
                Mailman m2 = new Mailman();
                m2.start();
                Mailman m3 = new Mailman();
                m3.start();
            }
    }

    点赞 评论 复制链接分享
  • qq_40062618 qq_1113502097 2月前

    你原本的目的因当是三个快递员一共发一百次,因此三个快递员应当共享一个计数器锁,也就是把计算的设为静态变量并对其加锁。而不是对线程加锁。

    点赞 评论 复制链接分享
  • weixin_42534024 何必要如此 2月前

    你这是3各快递员都把这100次快递发了一遍并且 还是还是一个一个的去送的快递没有同时进行 建议用公共变量AtomicInteger每次自增后的值作为快递数组的index

    点赞 评论 复制链接分享
  • hunger_wang hunger_wang 2月前

    你这样达不到效果,3个线程会每个都发送100个快递。因为采用成员变量index,3个线程之间没有交互。可以像下面这样(不过同一时刻也只有一个线程发送,吞吐量也比较低,大家都抢Mailman.class这把锁):

        private static class Expresses {
            private String name;
         
            public Expresses() {
            }
         
            public String getName() {
                return name;
            }
         
            public void setName(String name) {
                this.name = name;
            }
         
            public Expresses(String name) {
                this.name = name;
            }
         
        }
        
        private static class Mailman extends Thread{
            
            private static volatile int curr = 0;
            private static Expresses[] ex = new Expresses[100];
            static {
                for (int i = 0; i < 100; i++) {
                    // 给100个快递赋予 名称
                    ex[i] = new Expresses("快递-->"+i);
                }
            }
         
    //        private int index;
            private int number;
         
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    synchronized (Mailman.class) {
                        if (curr < 100) {
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //遍历得到对象数组每一个对象
    //                        Expresses e = ex[index++];
                            Expresses e = ex[curr];
                            // 输入那个线程(快递员)派发了哪一份快递
                            System.out.println(Thread.currentThread().getName()+"派送了"+e.getName()+"快递");
                            number++;
                        }
                        
                        curr++;
                    }
                }
                System.out.println(getName() + "发了" + number+"份快递");
            }
         
        }
        
        public static void main(String[] args) {
            Mailman m1 = new Mailman();
            m1.start();
            Mailman m2 = new Mailman();
            m2.start();
            Mailman m3 = new Mailman();
            m3.start();
        }

    点赞 评论 复制链接分享
  • qq_43243317 穿白衬衣的少年 2月前

    问题呢

    点赞 评论 复制链接分享

为你推荐