原创文章,欢迎转载。转载请注明:转载自 祥的博客 原文链接:http://blog.csdn.net/humanking7/article/details/43541387
API中解释: 暂停当前正在执行的线程对象,并执行其他线程。
注意:这里的其他也包含当前线程,即,当前线程也能够再次抢占CPU。
API解释:使当前线程暂停millis所指定的毫秒,转到执行其它线程。
public class MyRunnable implements Runnable{
private int num = 100;
@Override
public void run() {
while(true){
System.out.println(Thread.currentThread().getName() + "@: " + this.num);
this.num --;
Thread.yield(); //为了更容易产生错误
if(this.num < 0){
break;
}
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread th1 = new Thread(myRunnable,"线程A");
Thread th2 = new Thread(myRunnable,"线程B");
th1.start();
th2.start();
}
}
上述错误就是典型的多线程访问数据错误。
我来试着分析一下产生这个错误的原因:
System.out.println(Thread.currentThread().getName() + "@: " + this.num);
),被线程A抢到CPU了;num
还没没有执行自减操作,即num == 100
;线程A@:94
时,线程A抢到了CPU;线程B@:100
,其实此时num == 93
,只是原来把100
数据已经写进了程序的堆栈中;num
自减,即num == 92
;public class MyRunnable implements Runnable{
private int num = 100;
@Override
public void run() {
while(true){
System.out.println(Thread.currentThread().getName());
synchronized(this){
System.out.println(Thread.currentThread().getName() + "@: " + this.num);
this.num --;
Thread.yield();//为了更容易产生错误
if(this.num < 0){
break;
}
}
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread th1 = new Thread(myRunnable,"线程A");
Thread th2 = new Thread(myRunnable,"线程B");
th1.start();
th2.start();
}
}
我来分析一下用红框标记结果的执行流程。
分析之前先设定代码System.out.println(Thread.currentThread().getName());
为代码1,设定代码System.out.println(Thread.currentThread().getName() + "@: " + this.num);
为代码2。
真是绕啊,分析完毕,不知道有没有什么错误,还望大家批评指正,共同进步。