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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© enjoy 中级黑马   /  2015-2-9 14:37  /  1504 人查看  /  15 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 enjoy 于 2015-2-10 11:19 编辑

public class ThreadDemo implements Runnable{

private  int  piao;
public static void main (String[] args){
        piao p=new piao();
        ThreadDemo ThreadDemo=new ThreadDemo(p);
        ThreadDemo ThreadDemo1=new ThreadDemo(p);
        new Thread(ThreadDemo).start();
        new Thread(ThreadDemo1).start();
// 这两个线程公用类piao里面的piao的值吗?为什么打印出来的是两个线程都从100-1
}


public ThreadDemo(){
        
}
public ThreadDemo(piao p){
        this.piao=p.piao;
        
}
public void run(){
        while(piao>0){
                piao--;
                System.out.println(Thread.currentThread().getName()+"------------------->"+piao);
        }
}
}

//定义票的总张数
class piao {
        
        public  int piao=100;
        
}


为什么程序输出200条数据呢?连个线程不公用同一个对象吗?两个线程都是在操作同一个对象的值,为什么还出这样的结果呢?请大神帮忙看看!!万分感谢!!!

评分

参与人数 1技术分 +1 收起 理由
万合天宜 + 1 加油~

查看全部评分

15 个回复

倒序浏览
本帖最后由 书生灬流年 于 2015-2-9 14:50 编辑

因为你创建了2ThreadDemo个对象。public static void main (String[] args){
        piao p=new piao();
        ThreadDemo ThreadDemo=new ThreadDemo(p);
       // ThreadDemo ThreadDemo1=new ThreadDemo(p);
        new Thread(ThreadDemo).start();
        new Thread(ThreadDemo).start();
// 这两个线程公用类piao里面的piao的值吗?为什么打印出来的是两个线程都从100-1
}

评分

参与人数 1技术分 +1 收起 理由
lwj123 + 1

查看全部评分

回复 使用道具 举报
楼上正解。。
回复 使用道具 举报
书生灬流年 发表于 2015-2-9 14:48
因为你创建了2ThreadDemo个对象。public static void main (String[] args){
        piao p=new piao();
  ...

new Thread(ThreadDemo).start();这句话执行以后才是创建线程对吗?
ThreadDemo ThreadDemo=new ThreadDemo(p);这句话创建出来就相当于创建了一个对象,跟线程没关系对吗?
回复 使用道具 举报
enjoy 发表于 2015-2-9 16:45
new Thread(ThreadDemo).start();这句话执行以后才是创建线程对吗?
ThreadDemo ThreadDemo=new ThreadDe ...

new Thread(ThreadDemo).start();这句话执行以后才是创建线程对吗?
这句代码是开启线程。
ThreadDemo ThreadDemo=new ThreadDemo(p)
这句代码是创建了一个Runnable接口子类对象,将其作为参数传递给Thread类构造函数后创建线程。
回复 使用道具 举报
enjoy 发表于 2015-2-9 16:45
new Thread(ThreadDemo).start();这句话执行以后才是创建线程对吗?
ThreadDemo ThreadDemo=new ThreadDe ...

new Thread(ThreadDemo).start();这句话执行以后才是创建线程对吗?
这句代码是开启线程。
ThreadDemo ThreadDemo=new ThreadDemo(p)
这句代码是创建了一个Runnable接口子类对象,将其作为参数传递给Thread类构造函数后创建线程。
回复 使用道具 举报
这个问题是多线程的线程安全隐患。1.多个线程操作共享数据。2.操作共享数据的代码有多条!你可以看后面的视频,加入同步锁可以解决该问题!
回复 使用道具 举报
private int piao;是ThreadDemo 的特有数据,你new两个ThreadDemo 对象自然会有200张票啊。还有一点你代码的命名不怎么规范。
回复 使用道具 举报
enjoy 中级黑马 2015-2-10 11:16:14
9#
㏒假™面具 发表于 2015-2-9 18:54
这个问题是多线程的线程安全隐患。1.多个线程操作共享数据。2.操作共享数据的代码有多条!你可以看后面的视 ...

嗯嗯,同步锁我知道,现在就是不明白共享数据的对象。是怎么分的,看了大家给的帮助,有点明白了,谢谢了
回复 使用道具 举报
enjoy 中级黑马 2015-2-10 11:17:44
10#
lwj123 发表于 2015-2-9 19:48
private int piao;是ThreadDemo 的特有数据,你new两个ThreadDemo 对象自然会有200张票啊。还有一点你代码 ...

非常感谢。我开始的时候把实现runnable理解成就是线程了!
回复 使用道具 举报
你的代码好乱,看着都累,主要是你的代码不规范。首先一个问题是你定义的类piao类名首字母没有大写;其次,你应该在自定义类piao里面实现Runnable接口,并封装代码,只在main方法中调用。通过实现Runnable接口实现多线程,你创建几个Thread对象,就是几个线程,而不是去创建你的测试类。归纳一下实现Runnable接口的方式:1.自定义类实现Runnable接口。2.重写run()方法。3.创建自定义类的对象。4.创建Thread类的对象,把自定义类的对象作为构造参数传递。5调用Thread类的start()方法即可。
代码:
public class Ticket implements Runnable
{
        private int tickets = 100;
        public void run() {
                while (true) {
                        if (tickets > 0) {
                                System.out.println(Thread.currentThread().getName() +(tickets--) + "张票");
                        }
                }
        }
}
//-------------------------------------------------
public class TicketDemo {
        public static void main(String[] args) {
                Ticket t = new Ticket();
                Thread t1 = new Thread(t,);
                Thread t2 = new Thread(t,);
                t1.start();
                t2.start();
        }
}
回复 使用道具 举报
边晓炎 来自手机 中级黑马 2015-2-11 14:55:11
12#
其实跟new thread没什么关系!只之所以会出现这种情况!是你没理解操作共享数据是线程中处理,还是在数据源那里处理!两个线程都在处理相同数据,但是不是同一份,而是各处理各的那份!传票的对象进去不是要你直接把票减减,而是调用票对象中操作票数量的方法!这样才是在共享数据!
回复 使用道具 举报
enjoy 中级黑马 2015-2-26 09:51:04
13#
边晓炎 发表于 2015-2-11 14:55
其实跟new thread没什么关系!只之所以会出现这种情况!是你没理解操作共享数据是线程中处理,还是在数据源 ...

共享数据是线程对吗?

点评

线程共享同一个数据!  发表于 2015-2-28 10:16
回复 使用道具 举报
enjoy 中级黑马 2015-2-28 14:20:00
14#
enjoy 发表于 2015-2-26 09:51
共享数据是线程对吗?

谢谢!!!
回复 使用道具 举报
huangchunwei 来自手机 中级黑马 2015-3-5 08:27:34
15#
代码看着真累啊。。话说也没个注释啥的。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马