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

现有一百个快递待派发,定义快递类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();

    }

 

你这样达不到效果,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();
    }

问题呢

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

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

无锁的实现。

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