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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 于星星 中级黑马   /  2012-7-18 11:54  /  1443 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. package com.itheima.thread;

  2. public class Test_03 {
  3.         public static void main(String[] args) {
  4.                 // TODO 自动生成方法存根
  5.                 TxtThread tt = new TxtThread();
  6.                 new Thread(tt).start();
  7.                 new Thread(tt).start();
  8.                 new Thread(tt).start();
  9.                 new Thread(tt).start();
  10.         }
  11. }

  12. class TxtThread implements Runnable {
  13.         int num = 20;
  14.         String str = new String();
  15.         public void run() {
  16.                 while (true) {
  17.                         synchronized (str) {//这里的锁?
  18.                                 if (num > 0) {
  19.                                         try {
  20.                                                 Thread.sleep(10);
  21.                                         } catch (Exception e) {
  22.                                                 e.getMessage();
  23.                                         }
  24.                                         System.out.println(Thread.currentThread().getName()
  25.                                                         + "this is " + num--);
  26.                                 }
  27.                         }
  28.                 }
  29.         }
  30. }
复制代码
我不明白的是:TxtThread也是一个类,每创建一个它的对象就会拥有它的属性,因此num,str不是共享的,不存在访问冲突的情况
  另外代码中synchronized (str) //这里获取的锁是哪一个对象的?我不是太懂synchronized的使用方法和原理

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

3 个回复

倒序浏览
synchronized (str) {//这里的锁?//这里的锁是str啊,就是上面的那个String str = new String();
20.                                if (num > 0) {/*根据下面的输出语句,不允许出现num<0的情况,由于CPU在各个线程之间不断的切换执行,
                                        如果不用锁,可能会输出num<0的情况*/

21.                                        try {

22.                                                Thread.sleep(10);

23.                                        } catch (Exception e) {

24.                                                e.getMessage();

25.                                        }

26.                                        System.out.println(Thread.currentThread().getName()

27.                                                        + "this is " + num--);

28.                                }

回复 使用道具 举报
1.你说的txtthread是一个类,但是不是创建了很多回,虽然开启很多线程!但只有一个tt因为:TxtThread tt = new TxtThread();
只创建了一个对象!所以也没有你所说的情况!访问还是会冲突的!
2.synchronized (str);锁只是一个标识,任何一个对象都可以作为锁,就像new一个Object一样;只要这个对象不改变!
就不会改变所得作用。str当然是一个锁,你说它属于谁?属于TxtThread这个类;但str的作用是一个锁;你不用str也可以;
synchronized的用途没有什么;就是为了锁住共享的资源!

你必须知道什么是多线程,开启多线程后,代码就会分好几个线程执行了,每个线程都是独立的!
但你的对象只有一个,那么那些会改变的东西(变量之类);也就是共享资源就会被多个线程用到;
这样一来很可能一个变量遭到两个线程的同时访问;在某些情况下,就会出错!不按我们想的那样走!
所以用synchronized(){}把可能出错的代码包起来。只允许一个线程访问!避免出错

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
TxtThread tt = new TxtThread();
new Thread(tt).start()
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
LZ 说的不错,TxtThread是一个类,每创建一个它的对象就会拥有它的属性,因此num,str不是共享的,不存在访问冲突的情况 ,
但是,看看这段儿代码,LZ可是只new了一个对象,其他的线程调用的都是这一个对象。

synchronized (str);这里的str只是代表一个对象,因为这里要传的参数只要是一个对象就行,无论是什么对象,当然一定要是再内存中唯一存在的对象,要不就没有意义了。
所以这里如果放置一个Object对象也是可以的。
代码中lz创建的线程执行的是同一个run,每个线程都可以自由进入while中,但是要执行while中的代码,就必须先经过synchronized (str)判断,如果有线程正在里面,不管是执行还是睡眠,它都是锁着的,其它线程进不去,只有那个线程执行完出来后其它线程才可进去执行。这样就实现了同一时间只有一个线程访问资源的目的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马