Java编程思想

线程装饰性花园练习问题总结

在做练习17的时候遇到一个问题,做下记录,代码如下:

public class Test17 {
    static class Count {
        public int count = 0;
        Random random = new Random(47);
        public synchronized int increamcount() {
            int temp = count;
            while (random.nextBoolean()) {
               Thread.yield();
            }
            return count = ++temp;
        }
        public synchronized int totalCount() {
            return count;
        }
    }

    static class Sensor implements Runnable{

        private int number = 0;

        private static Count count = new Count();

        private final int id;

        private static List<Sensor> sensorList = new ArrayList<>();

        public Sensor(int i) {
            id = i;
            sensorList.add(this);
        }

        public static void cancel() {
            canceled = true;
        }

        private static volatile boolean canceled = false;

        @Override
        public void run() {
            while (!canceled) {
                synchronized (this) {
                    number++;
//                    count.increamcount();
                }
//                System.out.println(this + " total : " + count.totalCount());
                //不能用以上注释掉的写法,因为在执打印的之前,count.increamcount()方法有可能被其他线程执行多次,所以会出现多个相同的count的结果
                System.out.println(this + " total : " + count.increamcount());

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    System.out.println("sleep interrupted");
                }
            }
            System.out.println("stopping " + this);
        }

        public String toString() {
            return "Sensor " + id + " : " + getValue();
        }

        public synchronized int getValue() {
            return number;
        }

        public static int getTotalValue() {
            return count.totalCount();
        }

        public static int sumEntrances() {
            int sum = 0;
            for(Sensor sensor : sensorList) {
                sum += sensor.getValue();
            }
            return sum;
        }
    }

    public static void main(String[] args) {
        ExecutorService executor =
                new ThreadPoolExecutor(1,17,60L,TimeUnit.MILLISECONDS,new SynchronousQueue<>());
        for (int i = 0; i < 5; i++) {
            executor.execute(new Sensor(i));
        }
        try {
            TimeUnit.SECONDS.sleep(10);
            Sensor.cancel();
            executor.shutdown();
            if(!executor.awaitTermination(250,TimeUnit.MILLISECONDS)) {
                System.out.println("Some tasks were not terminated");
            }
            System.out.println("total :" + Sensor.getTotalValue());
            System.out.println("Sum of sensor :" + Sensor.sumEntrances());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在我刚开始的写法中

 @Override
        public void run() {
            while (!canceled) {
                synchronized (this) {
                    number++;
                    count.increamcount();
                     //为了结果更清晰
                    System.out.println(this + " !!!!!!!");
                }
                System.out.println(this + " total : " + count.totalCount());
                //不能用以上注释掉的写法,因为在执打印的之前,count.increamcount()方法有可能被其他线程执行多次,所以会出现多个相同的count的结果
//                System.out.println(this + " total : " + count.increamcount());

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    System.out.println("sleep interrupted");
                }
            }
            System.out.println("stopping " + this);
        }

打印结果为:
Sensor 0 : 1 !!!
Sensor 2 : 1 !!!
Sensor 1 : 1 !!!
Sensor 4 : 1 !!!
Sensor 3 : 1 !!!
Sensor 4 : 1 total : 5
Sensor 1 : 1 total : 5
Sensor 2 : 1 total : 5
Sensor 0 : 1 total : 5
Sensor 3 : 1 total : 5
Sensor 3 : 2 !!!
Sensor 0 : 2 !!!
Sensor 0 : 2 total : 10
Sensor 2 : 2 !!!
Sensor 2 : 2 total : 10
Sensor 1 : 2 !!!
Sensor 1 : 2 total : 10
Sensor 3 : 2 total : 10
Sensor 4 : 2 !!!
Sensor 4 : 2 total : 10
Sensor 4 : 3 !!!
Sensor 4 : 3 total : 14
Sensor 2 : 3 !!!
Sensor 2 : 3 total : 15
Sensor 3 : 3 !!!
Sensor 3 : 3 total : 15
Sensor 0 : 3 !!!
Sensor 0 : 3 total : 15
Sensor 1 : 3 !!!
Sensor 1 : 3 total : 15
Sensor 2 : 4 !!!
Sensor 4 : 4 !!!
Sensor 4 : 4 total : 20
Sensor 0 : 4 !!!
Sensor 0 : 4 total : 20
Sensor 3 : 4 !!!
Sensor 3 : 4 total : 20
Sensor 1 : 4 !!!
Sensor 1 : 4 total : 20
Sensor 2 : 4 total : 20
Some tasks were not terminated
total :20
Sum of sensor :20
stopping Sensor 3 : 4
stopping Sensor 4 : 4
stopping Sensor 2 : 4
stopping Sensor 1 : 4
stopping Sensor 0 : 4

可以很清晰的看到在第一次sleep,在执行 System.out.println(this + " total : " + count.totalCount());前5个线程已经完成了增加操作。
其中会出现total重复的情况,经过排查,修改如下

//
@Override
        public void run() {
            while (!canceled) {
                synchronized (this) {
                    number++;
//                    count.increamcount();
                }
//                System.out.println(this + " total : " + count.totalCount());
                //不能用以上注释掉的写法,因为在执打印的之前,count.increamcount()方法有可能被其他线程执行多次,所以会出现多个相同的count的结果
                System.out.println(this + " total : " + count.increamcount());

                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    System.out.println("sleep interrupted");
                }
            }
            System.out.println("stopping " + this);
        }

打印结果:
Sensor 0 : 1 total : 1
Sensor 4 : 1 total : 5
Sensor 3 : 1 total : 4
Sensor 2 : 1 total : 3
Sensor 1 : 1 total : 2
Sensor 1 : 2 total : 6
Sensor 0 : 2 total : 7
Sensor 4 : 2 total : 10
Sensor 2 : 2 total : 9
Sensor 3 : 2 total : 8
Sensor 4 : 3 total : 11
Sensor 3 : 3 total : 12
Sensor 0 : 3 total : 13
Sensor 1 : 3 total : 14
Sensor 2 : 3 total : 15
Sensor 4 : 4 total : 16
Sensor 3 : 4 total : 17
Sensor 0 : 4 total : 18
Sensor 1 : 4 total : 19
Sensor 2 : 4 total : 20
Some tasks were not terminated
total :20
Sum of sensor :20
stopping Sensor 4 : 4
stopping Sensor 3 : 4
stopping Sensor 0 : 4
stopping Sensor 1 : 4
stopping Sensor 2 : 4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值