yield是放弃对象锁,使当前线程回到可运行状态,其他线程获得此锁,调用yield就已经放弃当前对象的锁了

解决方案 »

  1.   

    yield方法是让出CPU,不释放锁,让出CPU是啥概念,就是让CPU执行其他线程在LZ的代码里,没有看到main方法,没有看到有几个线程,也不知道各个线程都在做些什么事情,没法说这个操作是否必要另:jvm实现者可以自由实现yield,也就是说它只是一个hint,暗示当前线程让出CPU,至于让不让,就不好说了
      

  2.   

    呃~~~,说错了一点,yield不放弃锁,但是使当前运行中线程回到可运行状态,并使具有相同优先级的线程能够具有机会运行。在这里就不要从同步的角度来考虑了,而应该从CPU资源来考虑,当多个线程并发执行的时候,如果当前线程不是很急的话,就让它等一等,让别的线程先执行
      

  3.   

    <<Thinking in java>> 并发那一章的例子,//: concurrency/OrnamentalGarden.java.
    个人认为是在去掉"synchronized "时用的,在同步的时候,有和没有
    if(rand.nextBoolean()) // Yield half the time
          Thread.yield();
    结果一样。
    在去掉这个同步的时候,有和没有上面的语句,结果差别较大。
      

  4.   

    main方法是产生5个线程,每个线程都有各自的一个计数器,同时5个线程又共用Count这个总计数器.代码如下:import java.util.concurrent.*;
    import java.util.*;
    //总计数器
    class Count {
      private int count = 0;
      private Random rand = new Random(47);
      // Remove the synchronized keyword to see counting fail:
      public synchronized int increment() {
        int temp = count;
        if(rand.nextBoolean()){ // Yield half the time
    Thread.yield();
    }
        return (count = ++temp);
      }
      public synchronized 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;
      // Doesn't need synchronization to read:
      private final int id;
      private static volatile boolean canceled = false;
      // Atomic operation on a volatile field:
      public static void cancel() { canceled = true; }
      public Entrance(int id) {
        this.id = id;
        // Keep this task in a list. Also prevents
        // garbage collection of dead tasks:
        entrances.add(this);
      }
      public void run() {
        while(!canceled) {
          synchronized(this) {
            ++number;
          }
          System.out.println(this + " Total: " + count.increment());
          try {
            TimeUnit.MILLISECONDS.sleep(100);
          } catch(InterruptedException e) {
            System.out.println("sleep interrupted");
          }
        }
        System.out.println("Stopping " + this);
      }
      public synchronized int getValue() { return number; }
      public String toString() {
        return "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));
        // Run for a while, then stop and collect the data:
        TimeUnit.SECONDS.sleep(3);
        Entrance.cancel();
        exec.shutdown();
        if(!exec.awaitTermination(250, TimeUnit.MILLISECONDS))
          System.out.println("Some tasks were not terminated!");
        System.out.println("Total: " + Entrance.getTotalCount());
        System.out.println("Sum of Entrances: " + Entrance.sumEntrances());
      }
    } /* Output: (Sample)
    Entrance 0: 1 Total: 1
    Entrance 2: 1 Total: 3
    Entrance 1: 1 Total: 2
    Entrance 4: 1 Total: 5
    Entrance 3: 1 Total: 4
    Entrance 2: 2 Total: 6
    Entrance 4: 2 Total: 7
    Entrance 0: 2 Total: 8
    ...
    Entrance 3: 29 Total: 143
    Entrance 0: 29 Total: 144
    Entrance 4: 29 Total: 145
    Entrance 2: 30 Total: 147
    Entrance 1: 30 Total: 146
    Entrance 0: 30 Total: 149
    Entrance 3: 30 Total: 148
    Entrance 4: 30 Total: 150
    Stopping Entrance 2: 30
    Stopping Entrance 1: 30
    Stopping Entrance 0: 30
    Stopping Entrance 3: 30
    Stopping Entrance 4: 30
    Total: 150
    Sum of Entrances: 150
    *///:~
      

  5.   

    main方法是产生几个线程,每个线程都有一个自己的计数器,所有线程都共享Count这个计数器,无论哪个线程计数器增加都会改变Count计数器。
    完整代码如下:import java.util.concurrent.*;
    import java.util.*;//总的计数器
    class Count {
      private int count = 0;
      private Random rand = new Random(47);
      // Remove the synchronized keyword to see counting fail:
      public synchronized int increment() {
        int temp = count;
        if(rand.nextBoolean()){ // Yield half the time
    Thread.yield();
    }
        return (count = ++temp);
      }
      public synchronized 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;
      // Doesn't need synchronization to read:
      private final int id;
      private static volatile boolean canceled = false;
      // Atomic operation on a volatile field:
      public static void cancel() { canceled = true; }
      public Entrance(int id) {
        this.id = id;
        // Keep this task in a list. Also prevents
        // garbage collection of dead tasks:
        entrances.add(this);
      }
      public void run() {
        while(!canceled) {
          synchronized(this) {
            ++number;
          }
          System.out.println(this + " Total: " + count.increment());
          try {
            TimeUnit.MILLISECONDS.sleep(100);
          } catch(InterruptedException e) {
            System.out.println("sleep interrupted");
          }
        }
        System.out.println("Stopping " + this);
      }
      public synchronized int getValue() { return number; }
      public String toString() {
        return "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));
        // Run for a while, then stop and collect the data:
        TimeUnit.SECONDS.sleep(3);
        Entrance.cancel();
        exec.shutdown();
        if(!exec.awaitTermination(250, TimeUnit.MILLISECONDS))
          System.out.println("Some tasks were not terminated!");
        System.out.println("Total: " + Entrance.getTotalCount());
        System.out.println("Sum of Entrances: " + Entrance.sumEntrances());
      }
    } /* Output: (Sample)
    Entrance 0: 1 Total: 1
    Entrance 2: 1 Total: 3
    Entrance 1: 1 Total: 2
    Entrance 4: 1 Total: 5
    Entrance 3: 1 Total: 4
    Entrance 2: 2 Total: 6
    Entrance 4: 2 Total: 7
    Entrance 0: 2 Total: 8
    ...
    Entrance 3: 29 Total: 143
    Entrance 0: 29 Total: 144
    Entrance 4: 29 Total: 145
    Entrance 2: 30 Total: 147
    Entrance 1: 30 Total: 146
    Entrance 0: 30 Total: 149
    Entrance 3: 30 Total: 148
    Entrance 4: 30 Total: 150
    Stopping Entrance 2: 30
    Stopping Entrance 1: 30
    Stopping Entrance 0: 30
    Stopping Entrance 3: 30
    Stopping Entrance 4: 30
    Total: 150
    Sum of Entrances: 150
    *///:~
      

  6.   

    同意,increment()方法上面有注释:Remove the synchronized keyword to see counting fail
    在整个代码的下面也有说明,Count.increment()通过使用temp和yield(),增加了不使用synchronized失败的可能性
      

  7.   

    yield()方法
    使当前线程主动让出CPU片段并回到Runnable状态
    如有线程调用该方法还是会被锁住的,只不过这段代码让其他线程先运行而已