菜鸟的多线程问题
我模仿者写买票的程序,结果,发现一个有意思的现象,但自己解释不了,求指教!
正确的代码如下:
public class Thread1 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable() ;
Thread t1 = new Thread(mr,"线程-1") ;
Thread t2 = new Thread(mr,"线程-2") ;
t1.start();
t2.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for(;k>0;){
if( k == 0 )
System.out.println("当前线程["+Thread.currentThread().getName()+"]没票了");
System.out.println("当前线程["+Thread.currentThread().getName()+"]卖出票,还有的数量:"+(k--));
}
}
private int k = 10;
}
当前线程[线程-2]卖出票,还有的数量:10
当前线程[线程-2]卖出票,还有的数量:9
当前线程[线程-2]卖出票,还有的数量:8
当前线程[线程-2]卖出票,还有的数量:7
当前线程[线程-2]卖出票,还有的数量:6
当前线程[线程-2]卖出票,还有的数量:5
当前线程[线程-2]卖出票,还有的数量:4
当前线程[线程-2]卖出票,还有的数量:3
当前线程[线程-2]卖出票,还有的数量:2
当前线程[线程-2]卖出票,还有的数量:1
class MyRunnable implements Runnable{
@Override
public void run() {
for(int k = 10 ;k>0;){
if( k == 0 )
System.out.println("当前线程["+Thread.currentThread().getName()+"]没票了");
System.out.println("当前线程["+Thread.currentThread().getName()+"]卖出票,还有的数量:"+(k--));
}
}
}
当前线程[线程-2]卖出票,还有的数量:10
当前线程[线程-2]卖出票,还有的数量:9
当前线程[线程-2]卖出票,还有的数量:8
当前线程[线程-2]卖出票,还有的数量:7
当前线程[线程-2]卖出票,还有的数量:6
当前线程[线程-2]卖出票,还有的数量:5
当前线程[线程-2]卖出票,还有的数量:4
当前线程[线程-2]卖出票,还有的数量:3
当前线程[线程-2]卖出票,还有的数量:2
当前线程[线程-2]卖出票,还有的数量:1
当前线程[线程-1]卖出票,还有的数量:10
当前线程[线程-1]卖出票,还有的数量:9
当前线程[线程-1]卖出票,还有的数量:8
当前线程[线程-1]卖出票,还有的数量:7
当前线程[线程-1]卖出票,还有的数量:6
当前线程[线程-1]卖出票,还有的数量:5
当前线程[线程-1]卖出票,还有的数量:4
当前线程[线程-1]卖出票,还有的数量:3
当前线程[线程-1]卖出票,还有的数量:2
当前线程[线程-1]卖出票,还有的数量:1
for(int k = 10 ;k>0;){} public void run() {
for(;k>0;){
System.out.println("当前线程["+Thread.currentThread().getName()+"]卖出票,还有的数量:"+(k--));
if( k == 0 )
System.out.println("当前线程["+Thread.currentThread().getName()+"]没票了");
}
}
能出现第一种情况真是侥幸
k为成员变量时会出现资源竞争的问题,此时需要对共享资源进行同步(synchronized or lock)
建议看一下线程状态和CPU调度相关资料
1、k成为成员变量时会出现资源竞争?书上没写,能否解释下?
2、我的k成为for的临时变量时,到是没竞争了,可是咋多运行了一倍!我个人觉得,两个线程引用一个Runnable中的run(),那么怎么会引用出2倍?
能出现第一种情况真是侥幸
k为成员变量时会出现资源竞争的问题,此时需要对共享资源进行同步(synchronized or lock)
建议看一下线程状态和CPU调度相关资料
1、k成为成员变量时会出现资源竞争?书上没写,能否解释下?
2、我的k成为for的临时变量时,到是没竞争了,可是咋多运行了一倍!我个人觉得,两个线程引用一个Runnable中的run(),那么怎么会引用出2倍?
你这样肯定有问题啊,每个线程都执行一个单独的实例。 就是说你线程一里面的k和你线程二里面的k根本就不是一个。
你要把k放到一个公共区里面,而且还要加锁
哦,看错了。用的一个对象,你把k改成1000再试一下呢
也就是说,那个k变了?
可是,t1和t2是引用同一个Runnable中的run方法啊?那么他们引用的run()里面的内容也该相同吧?
这就是我问题的根本想问的!