Thread.yield后线程释放资源的时间节点

  • 当synchronized方法中进行调用Thread.yield,线程之间的cpu调度是怎么样的?

    class Count {
        private int count = 0;
        private Random rand = new Random(47);
    
        /**
         * 这里为了实现多线程之间的同步,increment标注为synchronized,
         * 同时里面调用yield,yield的作用就是暂时释放cpu时间,然后和所有
         * 同一优先级的线程竞争。
         * @return
         */
        public synchronized int increment() {
            int temp = count;
            if (rand.nextBoolean()) {
                System.out.println(Thread.currentThread() + ": thread yield"); //print1
                Thread.yield();
            }
            System.out.println(Thread.currentThread() + ": increment"); //print2
            return (count = ++temp);
        }
    
        public int value() {
            return count;
        }
    }
    class Entrance implements Runnable {
        /**
         * 这里定义了两个私有静态成员变量,类所有,也就是说所有对象是共享的。
         */
        private static Count count = new Count();
        private static List entrances = new ArrayList();
    
        private int number = 0;
        /**
         * 定义了final的成员变量,这里不要初始化,因为final代表常量,赋值后就不可改
         */
        private final int id;
        /**
         * 使用volatitle定义canceled,因此canceled是直接从内存中进行读写,不会通过缓冲区,属于原子操作
         */
        private static volatile boolean canceled = false;
        public static void cancel() {
            canceled = true;
        }
        public Entrance(int id) {
            this.id = id;
            entrances.add(this);
        }
    
        @Override
        public void run() {
            while (!canceled) {
                synchronized (this) {
                    ++number;
                }
                System.out.println(this + " Total: " +  count.increment()); //print3
                try {
                    System.out.println(Thread.currentThread() + ": Sleep 100ms"); //print4
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    System.out.println(e);
                }
            }
            System.out.println("Stopping " + this);
        }
    
        public synchronized int getValue() {
            return number;
        }
    
        public String toString() {
            return Thread.currentThread() + ": Entrance " + id + ": " + getValue();
        }
    
        public static int getTotalCount() {
            return count.value();
        }
    
        public static int sumEntrances() {
            int sum = 0;
            for (Entrance entrance: entrances) {
                sum += entrance.getValue();
            }
            return sum;
        }
    }
    public class OrnamentalGarden {
        public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++) {
                exec.execute(new Entrance(i));
            }
            TimeUnit.SECONDS.sleep(3);
            Entrance.cancel();
            exec.shutdown();
            if (exec.awaitTermination(250, TimeUnit.MILLISECONDS)) {
                System.out.println("Some tasks were not terminateed!");
            }
            System.out.println("Total: " + Entrance.getTotalCount());
            System.out.println("Sum of Entrances: " + Entrance.sumEntrances());
        }
    }
    终端输出:
        1、线程1,在increment中调用thread yield,然后当调用完成
        System.out.println(this + " Total: " +  count.increment()),线程1释放,线程5占用;
        2、线程5,没有调用thread yield,然后运行到sleep 100ms的时候释放cpu
        3、线程4,调用thread yield后,立马释放了cpu
        4、线程1,接着运行,进入sleep 100ms
        5、线程4,继续运行increment方法,退出前又释放了
        6、线程3,没有调用thread yield,然后运行到sleep 100ms的时候释放cpu
        7、线程4,运行了一条语句,又释放了cpu
        8、线程2,没有调用thread yield,然后运行到sleep 100ms的时候释放cpu
    结论:
        thread yield条用后,当前线程什么时候释放cpu是由系统管理的,有可能调用后立马释放也有可过阵子释放,而且和synchronized method无关,synchronized处理的是线程之间的同步,而不是代码块的原子操作。
    
    Thread[pool-1-thread-1,5,main]: thread yield
    Thread[pool-1-thread-1,5,main]: increment
    Thread[pool-1-thread-1,5,main]: Entrance 0: 1 Total: 1
    Thread[pool-1-thread-5,5,main]: increment
    Thread[pool-1-thread-5,5,main]: Entrance 4: 1 Total: 2
    Thread[pool-1-thread-5,5,main]: Sleep 100ms
    Thread[pool-1-thread-4,5,main]: thread yield
    Thread[pool-1-thread-1,5,main]: Sleep 100ms
    Thread[pool-1-thread-4,5,main]: increment
    Thread[pool-1-thread-3,5,main]: increment
    Thread[pool-1-thread-3,5,main]: Entrance 2: 1 Total: 4
    Thread[pool-1-thread-3,5,main]: Sleep 100ms
    Thread[pool-1-thread-4,5,main]: Entrance 3: 1 Total: 3
    Thread[pool-1-thread-2,5,main]: increment
    Thread[pool-1-thread-2,5,main]: Entrance 1: 1 Total: 5
    Thread[pool-1-thread-2,5,main]: Sleep 100ms
    Thread[pool-1-thread-4,5,main]: Sleep 100ms
    Thread[pool-1-thread-3,5,main]: thread yield
    Thread[pool-1-thread-3,5,main]: increment
    Thread[pool-1-thread-2,5,main]: increment
    Thread[pool-1-thread-2,5,main]: Entrance 1: 2 Total: 7
    Thread[pool-1-thread-2,5,main]: Sleep 100ms
    Thread[pool-1-thread-4,5,main]: increment
    Thread[pool-1-thread-4,5,main]: Entrance 3: 2 Total: 8
    Thread[pool-1-thread-4,5,main]: Sleep 100ms
    Thread[pool-1-thread-5,5,main]: thread yield
    Thread[pool-1-thread-3,5,main]: Entrance 2: 2 Total: 6
    Thread[pool-1-thread-3,5,main]: Sleep 100ms
    Thread[pool-1-thread-5,5,main]: increment
    Thread[pool-1-thread-1,5,main]: thread yield
    Thread[pool-1-thread-5,5,main]: Entrance 4: 2 Total: 9

你可能感兴趣的:(Java开发及测试)