首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 菜鸟纹问题:关于线程同步问题(见代码)
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-12 14:48:49 楼主
    public class TT implements Runnable {
    int b = 100;

    public synchronized void m1() throws Exception{
    b = 1000;
    Thread.sleep(5000);
    System.out.println("b = " + b);
    }

    public synchronized void m2() throws Exception {
    Thread.sleep(2500);
    b = 2000;
    }

    public void run() {
    try {
    m1();
    } catch(Exception e) {
    e.printStackTrace();
    }
    }

    public static void main(String[] args) throws Exception {
    TT tt = new TT();
    Thread t = new Thread(tt);
    t.start();

    tt.m2();
    System.out.println(tt.b);
    }
    }

    以上代码,输出的结果为:1000
                        b = 1000
    问题1:在main方法中为什么执行顺序会是先执行完tt.m2()方法后,再执行线程的t1()方法,最后执行System.out.println(tt.b)?
    既然是多线程,为什么不能先t1()方法,再执行tt.m2()方法,最后在执行System.out.println(tt.b)?

    问题2: 如果把m2()方法的Thread.sleep(2500)去掉,其输出结果为:2000
                                                            b = 1000
    其执行过程又是怎样?

    本人初学java,请各位大侠多多指教,谢谢。
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-12 16:13:061楼 得分:0
    Thread.sleep(2500); 是放在 run()方法中的 因为线程 是调用 run()方法后 同时 工作
    2件事 如果是 多线程 就是 做 多件 事情
    Thread.sleep(2500);着 句话的 意思是 过 2.5秒 在去做 run()方法中的 事
    你上面 Thread.sleep(5000); 加上下面的Thread.sleep(2500);
    就是 过7.5秒做 run()方法中的 内容
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-12 19:40:142楼 得分:0
    该回复于2008-01-15 14:56:01被版主删除
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-12 19:47:063楼 得分:0
    在多线程中,它们是同时执行的,只有当你定义好它们的优先级,它们才会有顺序啊,不然的话,都是同是执行的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-12 20:04:224楼 得分:0
    请注意一个问题
    线程启动是需要时间的,而且还需要CPU分配时间片给他
    Java code
    TT tt = new TT(); Thread t = new Thread(tt); t.start(); // 通知线程可以启动了,当不一定现在就归他,如果你的机器够快,CPU够多,也不排除t里面的先运行后,再运行下面这一句 tt.m2(); // 在绝大多数情况下,这句和上一句之间被分配给前面线程的几率就高多了,所以这个先被执行的几率要高 System.out.println(tt.b);


    tt.m2 里面一但sleep, 则线程就拿到了时间片,但他也马上sleep了,而且比主线程的长,结果主线程先觉醒了。
    由于线程秀面前更改了b=1000, 所以主线程打印时等于1000了

    如果主线程没有sleep, 同前面的理由,主线程继续运行的几率要非常高,所以b=2000, 打印出2000了。

    还是那句话,如果你的机器足够快,你的那个子线程一不小心先拿到了时间片,结果还是会有变动的。 这就是隐患。

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-12 20:23:555楼 得分:0
    现在都是多核了,多线程代码都不会写了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-15 01:18:156楼 得分:0
    m1()先启动 b被赋值为1000  sleep
    m2()启动 sleep
    执行  System.out.println(tt.b);这时的b = 1000;
    m2() sleep结束 继续执行 b = 2000;
    方法加锁后sleep()时方法内的变量拒绝任何访问,直到锁被解除
    m1() sleep结束 继续执行  System.out.println("b = " + b); 由于锁没解除 b 还是 1000
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-01-16 21:49:167楼 得分:0
    楼上的解答有些问题把?m2()执行的时候主线程sleep 就不继续往下执行了。。。。因此主方法里面也不会再打印。直到睡眠结束,继续执行b =2000 再打印。
    而且,方法sleep()后,成员变量并没有被锁住,是还可以访问的。呵呵
    我的机器是双核的,运行起来完全是两码事,所以这种问题也不好解决了。。。
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved