黑马程序员技术交流社区
标题:
多线程——实现runnable的疑问.
[打印本页]
作者:
莫道荣
时间:
2013-3-17 23:19
标题:
多线程——实现runnable的疑问.
本帖最后由 莫道荣 于 2013-3-18 20:54 编辑
package org.credo.thread;
public class FirstRunnable implements Runnable{
private int i;
public void run(){
for(;i<10;i++){
//当线程类实现Runnable接口时,
//如果想获取当前线程,只能用Thread.currentThread()方法.
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==2){
FirstRunnable fr=new FirstRunnable();
//通过new Thread(target,name)方法创建新线程
new Thread(fr,"newThread11").start();
new Thread(fr, "newThread22").start();
}
}
}
}
输出:
main 0
main 1
main 2
main 3
main 4
newThread11 0
newThread22 0
newThread22 2
main 5
main 6
main 7
main 8
main 9
newThread22 3
newThread22 4
newThread11 1
newThread11 6
newThread22 5
newThread11 7
newThread22 8
newThread11 9
输出让我有点额...不太理解,就那两个0....按理说应该是1,2线程都是0~9顺序的.
按理来说,i应该是连续的,也就是采用runnable接口的方式创建的多个线程可以共享线程类的实例属性.这是因为在这种方式下,程序所创建的Runnable对象只是线程的target,而多个线程可以共享同一个target,所以多个线程可以共享同一个线程类(实际上应该是线程的target类)的实例属性.
所以,很是不解,求解释了......高手.
复制代码
作者:
杨明宁
时间:
2013-3-17 23:27
1.多个线程确实可以共享target类的实例变量,你的例子已经告诉你这个事实了
2.至于为什么输出两个0,就是因为多个线程共享了该变量,而你这里的代码没有对 i 进行同步,所以就会出现相同值的问题啦
作者:
IT菜鸟
时间:
2013-3-17 23:49
我试了一下,你的代码,没有问题啊,跟你说的输出结果,完全不一样。你再检查一下。我的输出结果如下:
main 1
main 2
newThread11 0
newThread11 1
newThread11 2
newThread11 3
newThread11 4
newThread11 5
newThread11 6
newThread11 7
newThread11 8
newThread11 9
main 3
main 4
main 5
main 6
main 7
main 8
main 9
作者:
谢洋
时间:
2013-3-18 00:05
本帖最后由 谢洋 于 2013-3-18 00:11 编辑
05.public void run(){
06. for(;i<10;i++){
08. //当线程类实现Runnable接口时,
10. //如果想获取当前线程,只能用Thread.currentThread()方法.
//线程2先是挂在这,
12.
System.out.println(Thread.currentThread().getName()+" "+i);//i为两线程共享,当线程1刚好执行完这一句,还未来得及执行 i++线程2又执行到了这里,
注意:i++是循环后才执行的,就说线程1第一次执行,还没执行完,i还是0,这时线程2第一次又来,所以他第一来遇的i也是0
所以除了0可能出现两次,其他数字即不使同步也不会出两次,但可能有个别数字没有被找打印
14. }
16. }
作者:
黑马17期-闫东东
时间:
2013-3-18 21:34
public class FirstRunnable implements Runnable{
private int i;
public void run(){
for(;i<10;i++){
//当线程类实现Runnable接口时,
//如果想获取当前线程,只能用Thread.currentThread()方法.
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==2){
FirstRunnable fr=new FirstRunnable();
//通过new Thread(target,name)方法创建新线程
new Thread(fr,"newThread11").start();
new Thread(fr, "newThread22").start();
}
}
我的运行结果:
main 0
main 1
main 2
newThread11 0
main 3
newThread22 1
newThread11 1
newThread22 2
main 4
newThread22 4
newThread11 3
newThread22 5
main 5
newThread22 7
newThread11 6
newThread22 8
main 6
newThread11 9
main 7
main 8
main 9
程序开始只有主线程在运行,打印0,1,2
i=2 创建Runable的子类对象,开启了两个线程,cup在 主线程,Thread11,Thread22,之间切换执行。
下面是用匿名内部类创建线程:
new Thread("t1"){
public void run(){
for(int i=0;i<6;i++){
System.out.println(getName());
try{
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
}
}
};
new Thread(new Runnable(){
public void run(){
for(int x=0; x<3; x++){
System.out.println(Thread.currentThread().getName());
try{
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
}
}
},"T2").start();
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2