黑马程序员技术交流社区

标题: 进程问题 [打印本页]

作者: 史卜坤    时间: 2012-7-12 19:07
标题: 进程问题
将共享数据和操作数据的方法一并封装到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);//打印出来的结果也非常怪异居然有负数
  •                 }
  •         }
  • }

复制代码

作者: 陈淑飞    时间: 2012-7-12 19:12
synchronized方法中,用了this锁定。

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

同步方法中,有个while 死循环呢,肯定会出现负数呢。
作者: 黑马振鹏    时间: 2012-7-12 19:32
本帖最后由 啸傲江湖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执行权,他开始执行同步函数,因为函数里面是一直循环所以他一执行,就不会退出来,这样就是看到的只有一个线程在执行,因为另外一个线程根本没机会进入。
执行同步函数:是一个一直递减的函数,打印结果肯定能打印负数,这里不会有疑问的。



作者: 张天天    时间: 2012-7-12 21:31
当run方法前面加上了synchronized之后,就意味着只有当一个线程的run方法执行完毕后,
另一个线程才可以开始执行,但是现在,你在run方法中写了个死循环,
怎么样程序也执行不完了啊,所以另外一个线程就无法开始执行了。

还有你说在类中定义的那个Tickets与main方法中的有什么不同
除了你说的之外,我想最大的不同应该就是:定义的这样一个变量不会随着方法执行完毕
而自动释放,因为方法的执行是出栈,所以定义在方法中的,当方法执行完之后
Tickets  tickets = new Tickets();就会被释放(当然这个在main方法中有点特别)
但是定义在类中的,该对象会被存放在堆内存中,随着类的存在而存在。
作者: 黑马刘涛    时间: 2012-7-12 23:09
学习楼上的讲解。




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