本帖最后由 HM朱蛟 于 2013-3-29 23:12 编辑
楼主你好,看了许久,楼主的疑惑点我大致明白了 我说下我的看法吧 有什么不对的请指出 一起学习
首先,这个bank类的对象,他的对象是Cus里创建的,Bank b = new Bank()它才叫做是对象调用; 所以只能是b指向了Bank对象,该对象的方法也是在Cus类里run()里调用了b.add()方法,简单说,它也属于多线程执行代码的一部分。
其实你搞混了一个概念,this是指向当前对象的引用,这没错,但是Thread(c)并非是一个指向它的动作,他只是可以接收一个Runnable的子类对象引用,和Bank b = new Bank() 这样的对象调用是有区别的,
总结:
你的当前调用对象自始至终都只有一个,即 Bank b = new Bank();换句话说,你的this锁自始至终也只有一个。
只需要搞清楚Thread t1 = new Thread(c)只是开启一个线程,c是传递的参数,是为了让线程找到线程执行代码,而该线程代码又是放在run()方法中,run方法只能是实现了Runnable接口的子类来复写或者直接是继承了Thread类的子类来复写提供的。
总之要明白,Thread t1 = new Thread(c) 和Bank b = new Bank()的区别
希望可以帮到你。
另附一个验证同步函数的锁是this的例程,看懂了这个例子相信你对同步函数的锁就没什么疑问了:
思想: 用两个线程,一个线程分别用一种同步方式 线程1:用同步代码块 线程2:用同步函数 利用一个布尔标志位手动分流。 class Ticket implements Runnable { private int tick = 100; //卖100张票
//Object o = new Object();
boolean b = true;//标志位分流
public void run()//卖票的代码要被多个线程所执行,存在于run方法中 { if(b) while(true)//一直循环,无特殊意义 { //synchronized(o) synchronized(this) { if(tick>0)//不能卖出0号票 { try {Thread.sleep(10);} catch (Exception e) {} System.out.println(Thread.currentThread().getName()+"卖 :code"+tick--); //注意实现的话不能直接调用currentThread } } } else while(true)//一直循环,无特殊意义 show();//调用同步函数 }
synchronized void show() //同步函数的锁是this { if(tick>0)//不能卖出0号票 { try {Thread.sleep(10);} catch (Exception e) {}
System.out.println(Thread.currentThread().getName()+"卖 :show........."+tick--); //注意实现的话不能直接调用currentThread } } }
class TicketDemo { public static void main(String[] args) { Ticket t = new Ticket();//售票窗口 Thread t1 = new Thread(t); //传参 Thread t2 = new Thread(t); t1.start(); //开启线程 try {Thread.sleep(10);} catch (Exception e) {} t.b = false; t2.start(); } } 输出结果: Thread-1卖 :show.........2 Thread-0卖 :code1 Thread-1卖 :show.........0 --->错票 思考: 为何同步了还是有错票?思考点应放在2个前提上,前提1:至少双线程。 前提2:同一个锁。从2个前提着手。我们知道,run函数是会被对象调用的,那么他的synchronized锁就是this,那么我们不妨把同步代码块的锁也改成this试一试。因为他们操作的都是同一个数据。 synchronized(o)--->synchronized(this) 改了过后,结果正常了,那么说明,2个前提满足了,所以能断定,同步函数用的是this的锁。 |