Better

业精于勤荒于嬉

Synchronized

Better's Avatar 2017-12-19 Java

  1. 1. 锁代码块
  2. 2. 锁方法
    1. 2.1. synchronized关键字不能继承
    2. 2.2. 锁静态方法
  3. 3. 锁对象
  4. 4. 锁类
  5. 5. 参考

锁,是用来在多线程做同步操作,是线程同步的一种实现方式,锁住需要同步代码,只能让单个线程访问。
锁住的是一个对象,对于这被锁住的对象,加了锁的会同步访问,没有加锁的就随机访问。
锁代码块,方法,对象,类。要区分他们的作用范围
block<=Method<Object<Class

  • 锁Block的时候,锁方法所有的代码就相当于锁方法
  • 锁Object的时候,他的所有的方法都同步执行。
  • 锁Class的时候,他的所有类对象执行到这个锁的地方是,都同步。

锁代码块

一个线程访问锁住的代码块时,一定是按次序来。
在方法中对于余下没有锁住的是随机的。这个随机要看线程获取CPU的能力强弱,先获取就先执行。至于执行多少,要看在每个CPU执行片段期间到底执行了多少。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void run() {
for (int i = 0; i < 3; i++) {
Utils.log("randomBefore:" + Thread.currentThread().getName() + "," + i);
}
synchronized (TestRunnable.this) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Utils.log(Thread.currentThread().getName() + ":" + i);
}
}
for (int i = 0; i < 3; i++) {
Utils.log("randomAfter:" + Thread.currentThread().getName() + "," + i);
}
}

JSBySynchronizedBlock
被锁的代码块是同步访问,其他的就随机

锁方法

在方法前面加synchronized,public synchronized void method(){//todo}。作用范围是整个方法,而锁代码块的作用方法是synchronized{}花括号的内容。
所以以下两者是等效的

1
2
3
4
5
6
7
8
9
10
11
public synchronized void method()
{
// todo
}

public void method()
{
synchronized(this) {
// todo
}
}

synchronized关键字不能继承

synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承。

如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,必须显式地在子类的这个方法中加上synchronized关键字才可以同步。
还可以在子类方法中调用父类中的方法super,单余下的其他的代码还是非同步的。

在子类方法中加上synchronized关键字

1
2
3
4
5
6
class Parent {
public synchronized void method() { }
}
class Child extends Parent {
public synchronized void method() { }
}

在子类方法中调用父类的同步方法

1
2
3
4
5
6
class Parent {
public synchronized void method() { }
}
class Child extends Parent {
public void method() { super.method(); }
}

JSBySynchronizedExtend

  1. 在定义接口方法时不能使用synchronized关键字。
  2. 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步。

锁静态方法

1
2
3
public synchronized static void method() {
// todo
}

JSBySynchronizedStaticMethod

静态方法是属于类的而不属于对象的。同样的,synchronized修饰的静态方法锁定的是这个类的所有对象。

锁对象

1
2
3
4
5
6
7
8
public void method3(SomeObject obj)
{
//obj 锁定的对象
synchronized(obj)
{
// todo
}
}

JSBySynchronizedObject

对于这个被锁住的对象,调用该对象的所有的方法都会同步。然后,对于多个同时锁改对象的代码块内部也是同步的(不是该对象的其他的方法)也是同步的。

锁类

不是在类申明的时候加锁而是

1
2
3
4
5
6
7
class ClassName {
public void method() {
synchronized(ClassName.class) {
// todo
}
}
}

JSBySynchronizedClass
效果跟锁类的静态方法一样,对于类的所有对象,调用锁类方法都会同步。

参考

Java中synchronized的用法

This article was last updated on days ago, and the information described in the article may have changed.