同步锁可以是
- 锁对象
class Test1 {
String str = new String();
public void run() {
synchronized (str) {
}
}
}
- 锁实例(this)
class Test2 {
public void run() {
synchronized (this) {
}
}
}
注:如果不是同一个实例,比如new了两个Test2分别执行run,则锁失效
- 锁类对象(static)
class Test3 {
public static synchronized void increase(){
i++;
}
}
synchronized关键字的3种应用方式:
修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
前两个好理解,这边说下修饰代码块:
class Untitled {
public void show(){
System.out.println("111");
synchronized (this) {
System.out.println("showB..");
}
System.out.println("222");
}
}
以上println输出的顺序是
System.out.println("111");
在同步锁之前,不受影响,被调用时立即执行
System.out.println("222");
在同步锁之后,受影响,触发同步锁之后,会等待得到同步锁之后才会执行到
即:
111
//等待获得同步锁...
showB..
222
synchronized使用的几个重要概念
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
以上规则对其它对象锁同样适用.
同一个线程访问一个synchronized方法,同时还可以访问该锁的其他synchronized方法
Java并发编程 -- synchronized保证线程安全的原理
java synchronized(同步代码块)
mac 编译执行java文件
javac test.java
java test