黑马程序员技术交流社区

标题: 线程问题?出现问题,求解!!! [打印本页]

作者: 王海旺    时间: 2013-7-24 11:44
标题: 线程问题?出现问题,求解!!!
本帖最后由 杨兴庭 于 2013-7-25 23:00 编辑

为何出现死循环状况???求解
public class ThreadTest4
{
public static void main(String[] args)
{
// 使用同一个Runnable对象创建两个线程
Runnable r = new Runnable1();

Thread t1 = new Thread(r);
Thread t2 = new Thread(r);

t1.start();
t2.start();
}
}

class Runnable1 implements Runnable
{
int i;

@Override
public void run()
{
while(true)
{
// 此情况能够正常退出
i++;
System.out.println("Runnable1: " + i);

try
{
Thread.sleep((long)(Math.random() * 1000));
}
catch (InterruptedException e)
{
e.printStackTrace();
}

if(i == 5)
{
break;
}

}
}
}
还有个不能够正常退出。
public class ThreadTest4
{
public static void main(String[] args)
{
// 使用同一个Runnable对象创建两个线程
Runnable r = new Runnable1();

Thread t1 = new Thread(r);
Thread t2 = new Thread(r);

t1.start();
t2.start();
}
}

class Runnable1 implements Runnable
{
int i;

@Override
public void run()
{
while(true)
{
try
{
Thread.sleep((long)(Math.random() * 1000));
}
catch (InterruptedException e)
{
e.printStackTrace();
}

// 此情况不能够退出
i++;
System.out.println("Runnable1: " + i);

if(i == 5)
{
break;
}

}
}
}


作者: xuluheng718    时间: 2013-7-24 12:10
这是线程锁的问题,你没有给线程加锁,假如0线程i = 5运行到if(i==5)时候break了,但是1线程并没有退出,所以1线程会继续运行,因为i永远不会等于5了
所以1线程会一直运行下去,
你可以把System.out.println("Runnable1"+i)换成System.out.println(Thread.currentThread().getName() +"----->"+i)运行看看就知道问题所在了

作者: 草貌路飞    时间: 2013-7-24 12:12
第一种先加后睡在判断,当一个线程会先i++ 变成4后睡在那里,另一个进来再i++就是5了,这时两个线程在判断都是5,所以不会出现问题  第二种先睡的话如果i=4时两个都睡在那里,一个醒了以后加加变成5就退出了,另一个醒了也要加一次 就死了。
作者: 陈贺    时间: 2013-7-24 12:47
第一个假设t2一直在Thread.sleep((long)(Math.random() * 1000));停着,当t1的i=5时结束线程,然后t2动了此时t2也等于5,也结束线程。
第二个假设t2一直在Thread.sleep((long)(Math.random() * 1000));停着,当t1的i=5时结束线程,然后t2动了此时t2下面会出现i++;此时t2的i变成6了,就结束不了了。
作者: wyy283    时间: 2013-7-25 11:11
是线程锁的问题,你没有给线程加锁,假如0线程i = 5运行到if(i==5)时候break了,但是1线程并没有退出,所以1线程会继续运行,因为i永远不会等于5了
所以1线程会一直运行下去,
你可以把System.out.println("Runnable1"+i)换成System.out.println(Thread.currentThread().getName() +"----->"+i)运行看看就知道问题所在了

作者: xwf4348    时间: 2013-7-25 11:27
情况一假设t2一直在Thread.sleep((long)(Math.random() * 1000));停着,当t1的i=5时结束线程,然后t2动了此时t2也等于5,也结束线程。
情况二假设t2一直在Thread.sleep((long)(Math.random() * 1000));停着,当t1的i=5时结束线程,然后t2动了此时t2下面会出现i++;此时t2的i变成6了,就结束不了了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2