线程同步的使用(synchronized)

线程同步结论:当多个线程共同修改同一个资源时使用线程同步,一个资源使用一个同步锁,尽量缩小同步块内的代码。


线程同步:线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。 

你不一定要把同步锁声明为static或者public,但是你一定要保证相关的同步代码之间,一定要使用同一个同步锁。

同步锁:任何一个Object Reference都可以作为同步锁。我们可以把Object Reference理解为对象在内存分配系统中的内存地址。因此,要保证同步代码段之间使用的是同一个同步锁,我们就要保证这些同步代码段的 synchronized关键字使用的是同一个Object Reference,同一个内存地址。这也是为什么我在前面的代码中声明lock1的时候,使用了final关键字,这就是为了保证lock1的 Object Reference在整个系统运行过程中都保持不变 

public static final Object lock1 = new Object(); 

同步形式:

 f1() { 

synchronized(lock1){ // lock1 是公用同步锁 
  // 代码段 A 
// 访问共享资源 resource1 
// 需要同步 

synchronized  f2() { 
  // 代码段 B 
// 访问共享资源 resource1 
// 需要同步 


如果有10个线程同时执行代码段A,同时还有20个线程同时执行代码段B,那么这30个线程之间都是要进行同步的。 
这30个线程都要竞争一个同步锁lock1。同一时刻,只有一个线程能够获得lock1的所有权,只有一个线程可以执行代码段A或者代码段B。其他竞争失败的线程只能暂停运行,进入到该同步锁的就绪(Ready)队列

但是,我们要尽量避免这种直接把synchronized加在函数定义上的偷懒做法。因为我们要控制同步粒度。同步的代码段越小越好。

synchronized控制的范围越小越好。 

而且如果还有f3,f4 访问的resource2 则可以新建一个锁lock2,这样,f1()和f2()就会竞争lock1,而f3()和f4()就会竞争lock2。这样,分开来分别竞争两个锁,就可以大大较少同步锁竞争的概率,从而减少系统的开销。 

你可能感兴趣的:(线程同步的使用(synchronized))