解决方案 »

  1.   

    synchronized 
    加锁 同步
      

  2.   

    你这两个没有什么区别, ticket的读写都是线程不安全的。 至于你说的第二个例子不会错误, 我估计t1或者t2中的一个执行太快, 打印了从10到1,t2执行的时候直接拿到了0, 没有任何输出, 这只是巧合, 你多执行几次或则在run里面像第一个那样sleep一下就明白了
      

  3.   

    这和线程的创建方法没有关系~。楼主第二个例子没有加static修饰,那么每个对象的 ticket 是私有的,不是共享的。每个线程对应自己的ticket
      

  4.   

    楼主你想使资源共享的话那你就使用同步方法或者同步块啊!你使用synchronized关键字修饰某一个方法,使那个方法在调用时只用一个线程进入,然后关于属性上,我觉得吧,如果楼主使用的是私有属性的话还是加上get、set方法吧!方便调用
      

  5.   

    解决这种 多个线程共享资源,避免发生数据不一致的错误,有个“同步” 的概念,所以你需要去了解什么是同步及如何实现;其次,你可以了解下JVM内存模型,各种数据保存在哪些相应的内存区域,然后看哪些内存区是线程共享的;像static变量是存储在方法区的,创建的对象是存储在堆中,而方法区和堆都是线程共享的,若这些内存区的数据在线程间共享,就需要同步处理来确保安全操作。
      

  6.   

    个人理解如下(可能有错,可以随意批评指正):
    1. 对于例一,加了static表示这是一个类变量,那么每个实例都会共享它。但是由于多个thread如果同一时间片取到这个类变量并打印,那么就可能是打印出来的是相同的。这就是由于没有锁的原因(实际使用中,可以增加一个synchronized的getTickets()方法取这个变量解决这个问题)。
    2. 对于例二,这个确实没注意过,以前用runnable都只是因为方便扩展,例子中,这两个thread都是基于同一个runnable实例,姑且可以算是共用同样的资源且自动用到了同步锁。
      

  7.   

    实例化了一个Runnable接口的类可以给多个线程运行,这样多个线程运行的都是同一个Runnable类(比如你写的例2,new Thread(mt).start()都是运行mt.run()方法 ),这个实例化的Runnable类中的私有属性则可以被多个线程访问(注意不是static属性),这样不就做到了数据共享吗?但是在共享数据的时候最后做到数据同步,这样在做属性变更的时候就不会出错
      

  8.   

    谢谢以上各位朋友!
    嗯,我明白了。
    1、如果用继承Thread类,来生成N个线程,成员变量都是属于各自线程的。
    2、如果实现Runnable接口,来生成N个线程,成员变量只有一个,是共享的。随着CPU调度时机不同,可能会发生数据不一致性。