当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<Entrance> entrances = new ArrayList<Entrance>(); 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
Thread.yield后线程释放资源的时间节点
最新推荐文章于 2023-06-04 12:03:02 发布