synchronized(this)和synchronized(object)区别

synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下: 
synchronized(syncObject) {
//允许访问控制的代码
}
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。

对synchronized(this)的一些理解(很细致,感谢作者!)

 

 

我对synchronized(this)和synchronized(object)的理解:

误区一:synchronized关键字只能用在实现Runnable或者继承了Thread类的子类的方法里面。

正解:如果有一块代码(或方法)可能被多个线程同时访问,然后里面操作的数据修改操作可能因为不同线程的操作而不一致的时候,使用synchronized锁定这块代码,确保同时只有一个线程访问这个代码块。也就是说,关键字synchronized可以用在任何类的方法里面,即使该类没有实现Runnable接口或者继承Thread类。

 

误区二:synchronized(this)和synchronized(object)作用范围完全不同。

正解:当 多个线程 访问同一个类A 的 方法A()的时候
并且 这个方法A() 要求 一个线程执行完了之后 在给另外一个线程去执行

 那么  这个方法A()   9必须加上  synchronized 关键字

或者  在 该方法A()中  写上 synchronized(this//指代当前类A的实例){}

如果不在声明方法A()时 加上synchronized关键字 或者 不在方法A()中加上synchronized(this){}
同步块的时候


可以在 线程类的RUN 方法内
synchronized(Object //指代类A的实例){
 Object.A();
}
实现多线程同时有序访问该同步块内类A的方法A()的目的

 

object本身就包含this的情况。

this指代的是当前同步块所在方法所在的类,当不需要引用别的类的时候。

object指代的是需要调用的类,引用了别的类,且需要处理多线程并发访问时,object指代的是被引用的类。如果没有引用别的类,则指代的就是同步块所在方法所在的类本身。

 

 

例:

 

 


public class 访问类 {

 public void A方法() {
  //synchronized (this) {
   for (int i = 0; i < 100; i++) {
    System.out.println(Thread.currentThread().getName() + " i = "
      + i);
   }
  //}
 }

 public void B方法() {
  //synchronized (this) {
   for (int i = 0; i < 100; i++) {
    System.out.println(Thread.currentThread().getName() + " i = "
      + i);
   }
  //}
 }
}

 

 

 

 

 


public class 实例线程类 {
 public static void main(String[] args) {
  访问类 Object = new 访问类();

  Thread t1 = new Thread(new 线程A(Object));
  Thread t2 = new Thread(new 线程B(Object));
  t1.start();
  t2.start();
 }
}

class 线程A implements Runnable {
 private 访问类 object;

 public 线程A(访问类 object) {
  // TODO Auto-generated constructor stub
  this.object = object;
 }

 @Override
 public void run() {
  // TODO Auto-generated method stub
  synchronized (object) {
   object.A方法();
  }
 }

}

class 线程B implements Runnable {
 private 访问类 object;

 public 线程B(访问类 object) {
  // TODO Auto-generated constructor stub
  this.object = object;
 }

 @Override
 public void run() {
  // TODO Auto-generated method stub
   synchronized (object) {
   object.B方法();
   }
 }

}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: synchronized (this) 和其他变量的主要区别在于锁定对象的范围不同。 synchronized (this) 是在当前对象实例上锁定,即锁定当前对象的所有同步代码块,只有获得锁的线程才能执行同步代码块,其他线程则需要等待锁的释放。 而对于其他变量的同步代码块,需要指定一个共享的对象作为锁。通常情况下,我们会使用一个私有的 final 对象作为锁,这个对象不会被改变,以避免出现死锁等问题。 总之,synchronized (this) 更加方便,适用于对当前对象实例进行同步,而其他变量的同步则需要更加小心地处理锁的范围和对象。 ### 回答2: synchronized (this)是Java中用于实现线程同步的关键字,它的主要作用是确保在同一时间只有一个线程可以进入被synchronized块包裹的代码段。当一个线程进入synchronized (this)块时,它会获得当前对象的锁,其他线程在此期间无法进入该代码段,只能等待该线程执行完毕释放锁后才能够执行。 与此相比,其他变量并没有提供类似的线程同步机制。在多线程环境下,多个线程可以同时访问和修改同一个变量,没有任何机制来保证线程安全。这可能导致数据竞争和不一致性的问题。 使用synchronized (this)可以确保在同一时间内只有一个线程能够访问被synchronized包裹的代码段,从而避免了数据竞争和不一致性的问题。而其他变量则需要使用其他方式来实现线程安全性,比如使用volatile关键字、使用锁对象等。 需要注意的是,synchronized (this)是基于对象锁实现的,它只会对当前对象上锁,而不是对整个类或者其他对象上锁。因此,如果需要对整个类或者其他对象进行线程同步,需要使用其他方式,如synchronized (ClassName.class),或者使用实例化一个专门的锁对象。 总之,synchronized (this)是Java中用于实现线程同步的关键字,能够确保在同一时间内只有一个线程能够进入被synchronized块包裹的代码段。而其他变量并没有提供类似的线程同步机制,需要使用其他方式来实现线程安全性。 ### 回答3: synchronized (this)是Java中一种同步锁的机制,用于对当前对象实例进行同步控制。当多个线程访问同一个对象的synchronized(this)代码块时,只有一个线程能够执行该代码块,其他线程需要等待。 相比之下,其他变量的同步机制可以通过以下几种方式来实现: 1. synchronized (Object obj):通过指定一个非this对象来加锁,这个对象可以是任意的Java对象。这种方式可以实现不同线程对不同对象的互斥访问。 2. volatile变量:通过使用volatile关键字修饰变量,可以确保每个线程在访问该变量时都能读取到最新的值。这种机制适用于变量的读操作比写操作更频繁的情况。 3. Atomic类:Java.util.concurrent.atomic包中提供了多种原子性的数据类型,如AtomicInteger、AtomicBoolean等。这些原子类具有自己的一些方法来保证对变量的操作是原子性的,从而避免了线程安全问题。 4. Lock接口:Java中提供了Lock接口作为同步锁的另一种实现方式。与synchronized不同,Lock接口需要显式地进行加锁和释放锁的操作,可以更灵活地控制线程的同步行为。 总结来说,synchronized (this)是针对当前对象实例进行同步控制的机制,而其他的同步变量机制可以针对不同的对象实例进行同步控制,或者通过使用特定的关键字或类来实现线程安全。根据具体的线程操作,可以选择不同的同步机制来保证多线程的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值