A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王海旺 中级黑马   /  2013-7-24 11:44  /  1299 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨兴庭 于 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;
}

}
}
}

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

5 个回复

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

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
第一种先加后睡在判断,当一个线程会先i++ 变成4后睡在那里,另一个进来再i++就是5了,这时两个线程在判断都是5,所以不会出现问题  第二种先睡的话如果i=4时两个都睡在那里,一个醒了以后加加变成5就退出了,另一个醒了也要加一次 就死了。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
第一个假设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了,就结束不了了。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
是线程锁的问题,你没有给线程加锁,假如0线程i = 5运行到if(i==5)时候break了,但是1线程并没有退出,所以1线程会继续运行,因为i永远不会等于5了
所以1线程会一直运行下去,
你可以把System.out.println("Runnable1"+i)换成System.out.println(Thread.currentThread().getName() +"----->"+i)运行看看就知道问题所在了

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
情况一假设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了,就结束不了了。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马