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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 史卜坤 中级黑马   /  2012-7-12 19:07  /  1512 人查看  /  4 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

将共享数据和操作数据的方法一并封装到Runnable的实现子类中,然后在主方法中new其实例对象,将这个实例对象传个创建的两个匿名Thread对象,并开启运行。为何出现诡异的结果呢?麻烦大家帮忙看看!谢谢先!
  • public class SaleTickets{
  •         //static Tickets  tickets = new Tickets();//这里和(1)处除了他是随类的创建而创建,
  •                                                 //存储在静态区,以及共享外还有什么区别吗?
  •         public static void main(String[] args) {
  •                  Tickets  tickets = new Tickets();//(1)
  •                 new Thread(tickets).start();//调用tickets身上的run方法将count--
  •             new Thread(tickets).start();//也是调用tickets身上的run方法将count--
  •         }
  • }
  • //将共享数据和操作数据的方法一并封装到Runnable的实现子类中
  • class Tickets implements Runnable{
  •         private int count = 10000;
  •         @Override
  •         public /*synchronized*/ void  run(){//这里为何加上同步另外一个进程就无法启动呢?
  •                 while(true){
  •                  count--;
  •                  System.out.println(Thread.currentThread().getName()+"|"+count);//打印出来的结果也非常怪异居然有负数
  •                 }
  •         }
  • }

复制代码

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 赞一个!

查看全部评分

4 个回复

正序浏览
学习楼上的讲解。
回复 使用道具 举报
当run方法前面加上了synchronized之后,就意味着只有当一个线程的run方法执行完毕后,
另一个线程才可以开始执行,但是现在,你在run方法中写了个死循环,
怎么样程序也执行不完了啊,所以另外一个线程就无法开始执行了。

还有你说在类中定义的那个Tickets与main方法中的有什么不同
除了你说的之外,我想最大的不同应该就是:定义的这样一个变量不会随着方法执行完毕
而自动释放,因为方法的执行是出栈,所以定义在方法中的,当方法执行完之后
Tickets  tickets = new Tickets();就会被释放(当然这个在main方法中有点特别)
但是定义在类中的,该对象会被存放在堆内存中,随着类的存在而存在。
回复 使用道具 举报
本帖最后由 啸傲江湖007 于 2012-7-12 19:39 编辑

public class SaleTickets{
        //static Tickets  tickets = new Tickets();//这里和(1)处除了他是随类的创建而创建,
                                                //存储在静态区,以及共享外还有什么区别吗? 应该没有其他太大区别吧
        public static void main(String[] args) {
                 Tickets  tickets = new Tickets();//(1)
                new Thread(tickets).start();//调用tickets身上的run方法将count--
            new Thread(tickets).start();//也是调用tickets身上的run方法将count--
        }
}
//将共享数据和操作数据的方法一并封装到Runnable的实现子类中
class Tickets implements Runnable{
        private int count = 10000;
        @Override
        public synchronized void  run(){//这里为何加上同步另外一个进程就无法启动呢? 因为run()加了同步后只能是一个线程进来执行,函数里面又是while(true)所以一个线程进来后另一个根本进不来。
             while(true){
                 count--;
        //便于观察打印结果
          try {
        Thread.sleep(100);
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
                 System.out.println(Thread.currentThread().getName()+"|"+count);//打印出来的结果也非常怪异居然有负数
                }
        }
}

首先我在同步函数中加上sleep()这样便于观察打印结果, 两个线程,名字暂且为Thread-1和Thread-2  ,现在的程序是多线程程序没问题,两个线程都准备执行,假设第一个线程抢到了CPU执行权,他开始执行同步函数,因为函数里面是一直循环所以他一执行,就不会退出来,这样就是看到的只有一个线程在执行,因为另外一个线程根本没机会进入。
执行同步函数:是一个一直递减的函数,打印结果肯定能打印负数,这里不会有疑问的。


评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 赞一个!

查看全部评分

回复 使用道具 举报
synchronized方法中,用了this锁定。

两个匿名Thread对象,都用了同一个锁。所有只有一个线程在运行呢。

同步方法中,有个while 死循环呢,肯定会出现负数呢。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马