Java语言的关键字——synchronized

简介:Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。

意义:方法加锁。


用法:它包括两种用法:synchronized 方法和 synchronized 块。

synchronized 方法

1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.
  例如:
public synchronized void synMethod(){
  //方法体
  }


2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁.例如:
public int synMethod(inta1){
  synchronized(a1){
  //一次只能有一个线程进入
  }
  }


  3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.例如:
public class MyThread implements Runnable{
  public static void main(Stringargs[]){
  MyThreadmt=newMyThread();
  Threadt1=newThread(mt,"t1");
  Threadt2=newThread(mt,"t2");
  Threadt3=newThread(mt,"t3");
  Threadt4=newThread(mt,"t4");
  Threadt5=newThread(mt,"t5");
  Threadt6=newThread(mt,"t6");
  t1.start();
  t2.start();
  t3.start();
  t4.start();
  t5.start();
  t6.start();
  }
 public void run(){
  synchronized(this){
  System.out.println(Thread.currentThread().getName());
  }
  }
  }

  
对于3,如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行.在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁,而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源,就不需要只为了让一个线程使用其中一部分资源,就将所有线程都锁在外面。由于每个对象都有锁,可以如下所示使用虚拟对象来上锁:
class FineGrainLock{
  MyMemberClassx,y;
  Objectxlock=newObject(),ylock=newObject();
  publicvoidfoo(){
  synchronized(xlock){
  //accessxhere
  }
  //dosomethinghere-butdon'tusesharedresources
  synchronized(ylock){
  //accessyhere
  }
  }
  public void bar(){
  synchronized(this){
  //accessbothxandyhere
  }
  //dosomethinghere-butdon'tusesharedresources
  }
  }



  4.synchronized后面括号里是类,此时,线程获得的是对象锁.例如:
classArrayWithLockOrder{
  privatestaticlongnum_locks=0;
  privatelonglock_order;
  privateint[]arr;
  publicArrayWithLockOrder(int[]a)
  {
  arr=a;
  synchronized(ArrayWithLockOrder.class){//-----这里
  num_locks++;//锁数加1。
  lock_order=num_locks;//为此对象实例设置唯一的lock_order。
  }
  }
  publiclonglockOrder()
  {
  returnlock_order;
  }
  publicint[]array()
  {
  returnarr;
  }
  }
  classSomeClassimplementsRunnable
  {
  publicintsumArrays(ArrayWithLockOrdera1,
  ArrayWithLockOrdera2)
  {
  intvalue=0;
  ArrayWithLockOrderfirst=a1;//保留数组引用的一个
  ArrayWithLockOrderlast=a2;//本地副本。
  intsize=a1.array().length;
  if(size==a2.array().length)
  {
  if(a1.lockOrder()>a2.lockOrder())//确定并设置对象的锁定
  {//顺序。
  first=a2;
  last=a1;
  }
  synchronized(first){//按正确的顺序锁定对象。
  synchronized(last){
  int[]arr1=a1.array();
  int[]arr2=a2.array();
  for(inti=0;i<size;i++)
  value+=arr1[i]+arr2[i];
  }
  }
  }
  returnvalue;
  }
  publicvoidrun(){
  //
  }
  }
对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值