疑惑,一个方法同步了为什么中间还有yield让步 yield是放弃对象锁,使当前线程回到可运行状态,其他线程获得此锁,调用yield就已经放弃当前对象的锁了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 yield方法是让出CPU,不释放锁,让出CPU是啥概念,就是让CPU执行其他线程在LZ的代码里,没有看到main方法,没有看到有几个线程,也不知道各个线程都在做些什么事情,没法说这个操作是否必要另:jvm实现者可以自由实现yield,也就是说它只是一个hint,暗示当前线程让出CPU,至于让不让,就不好说了 呃~~~,说错了一点,yield不放弃锁,但是使当前运行中线程回到可运行状态,并使具有相同优先级的线程能够具有机会运行。在这里就不要从同步的角度来考虑了,而应该从CPU资源来考虑,当多个线程并发执行的时候,如果当前线程不是很急的话,就让它等一等,让别的线程先执行 <<Thinking in java>> 并发那一章的例子,//: concurrency/OrnamentalGarden.java.个人认为是在去掉"synchronized "时用的,在同步的时候,有和没有if(rand.nextBoolean()) // Yield half the time Thread.yield();结果一样。在去掉这个同步的时候,有和没有上面的语句,结果差别较大。 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: 1Entrance 2: 1 Total: 3Entrance 1: 1 Total: 2Entrance 4: 1 Total: 5Entrance 3: 1 Total: 4Entrance 2: 2 Total: 6Entrance 4: 2 Total: 7Entrance 0: 2 Total: 8...Entrance 3: 29 Total: 143Entrance 0: 29 Total: 144Entrance 4: 29 Total: 145Entrance 2: 30 Total: 147Entrance 1: 30 Total: 146Entrance 0: 30 Total: 149Entrance 3: 30 Total: 148Entrance 4: 30 Total: 150Stopping Entrance 2: 30Stopping Entrance 1: 30Stopping Entrance 0: 30Stopping Entrance 3: 30Stopping Entrance 4: 30Total: 150Sum of Entrances: 150*///:~ 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: 1Entrance 2: 1 Total: 3Entrance 1: 1 Total: 2Entrance 4: 1 Total: 5Entrance 3: 1 Total: 4Entrance 2: 2 Total: 6Entrance 4: 2 Total: 7Entrance 0: 2 Total: 8...Entrance 3: 29 Total: 143Entrance 0: 29 Total: 144Entrance 4: 29 Total: 145Entrance 2: 30 Total: 147Entrance 1: 30 Total: 146Entrance 0: 30 Total: 149Entrance 3: 30 Total: 148Entrance 4: 30 Total: 150Stopping Entrance 2: 30Stopping Entrance 1: 30Stopping Entrance 0: 30Stopping Entrance 3: 30Stopping Entrance 4: 30Total: 150Sum of Entrances: 150*///:~ 同意,increment()方法上面有注释:Remove the synchronized keyword to see counting fail在整个代码的下面也有说明,Count.increment()通过使用temp和yield(),增加了不使用synchronized失败的可能性 yield()方法使当前线程主动让出CPU片段并回到Runnable状态如有线程调用该方法还是会被锁住的,只不过这段代码让其他线程先运行而已 HashMap<String, Action> 后在的参数是什么意思 解释下java的求模运算~17.25%0.7=? 求下面这段文字来自的书或者专辑技术文章 插入数据问题(超出打开游标的最大数...) java修改pdf文件----急!! 安装J2SDK1.4.2遇到DLL_.ini问题 散分200讨论JAVA的GC机制!!!!!!!!!!!!!!!!!!!!!!!!高手请进 请到这里领分…… 关于防火墙的问题 java写文件的问题! 请问下如何将文件放入内存里然后读取呢 线程问题
个人认为是在去掉"synchronized "时用的,在同步的时候,有和没有
if(rand.nextBoolean()) // Yield half the time
Thread.yield();
结果一样。
在去掉这个同步的时候,有和没有上面的语句,结果差别较大。
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
*///:~
完整代码如下: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
*///:~
在整个代码的下面也有说明,Count.increment()通过使用temp和yield(),增加了不使用synchronized失败的可能性
使当前线程主动让出CPU片段并回到Runnable状态
如有线程调用该方法还是会被锁住的,只不过这段代码让其他线程先运行而已