synchronized修饰非静态方法,是对调用该方法的对象加锁,称为对象锁。
synchronized修饰静态方法,是对该类加锁,称为类锁。
每个对象的锁唯一。
对象内所有加锁的非静态方法共用一把锁(即对象锁),一个加锁非静态方法执行,另一个加锁非静态方法就不能执行了,要等待持有锁的线程释放锁,不同对象之间的方法不互相作用。
类中的所有加锁的静态方法共用一把锁(即类锁),一个加锁的静态方法执行,同类另一个加锁静态方法就不能执行了,要等待持有锁的线程释放锁(对属于同一个类的两个对象的静态方法进行操作也会互斥执行)。
synchronized方法与synchronized代码块的区别:synchronized method(){}与synchronized(this){}之间没有什么区别。只是前者便于阅读理解,而后者可以更精确的控制冲突限制访问区域(粒度更小),锁的范围没有变,锁住的时间变短了因而性能更好。
加对象锁和加类锁之间互不相干,执行时候没有影响。
加锁方法的执行不会影响类/对象中未加锁的方法的执行。
对于synchronized(非this对象):
在多个线程持有“对象监视器”为同一对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块里的代码。
在多个线程持有“对象监视器”不是同一对象,同一时间synchronized(非this对象)同步代码块里的代码异步执行,互不影响。
synchronized(非this对象)与synchronized方法异步执行,互不影响。
synchronized(a)与synchronized(b)方法异步执行,互不影响。
全部代码如下:
package suo;
class Suo{
String s = new String();
String s1 = new String();
synchronized void fun1() throws InterruptedException{
System.out.println("加锁的非静态方法1开始执行");
Thread.sleep(2000);
System.out.println("加锁的非静态方法1执行结束");
}
synchronized void fun2() throws InterruptedException{
System.out.println("加锁的非静态方法2开始执行");
Thread.sleep(2000);
System.out.println("加锁的非静态方法2执行结束");
}
void fun5() throws InterruptedException{
synchronized (this) {
System.out.println("加锁的非静态方法5开始执行");
Thread.sleep(2000);
System.out.println("加锁的非静态方法5执行结束");
}
}
synchronized static void fun3() throws InterruptedException{
System.out.println("加锁的静态方法3开始执行");
Thread.sleep(2000);
System.out.println("加锁的静态方法3执行结束");
}
synchronized static void fun4() throws InterruptedException{
System.out.println("加锁的静态方法4开始执行");
Thread.sleep(2000);
System.out.println("加锁的静态方法4执行结束");
}
static void fun6() throws InterruptedException{
synchronized (Suo.class) {
System.out.println("加锁的静态方法6开始执行");
Thread.sleep(2000);
System.out.println("加锁的静态方法6执行结束");
}
}
void fun7(Integer i) throws InterruptedException{
// String s = new String();
synchronized (s) {
System.out.println("非静态方法7开始执行(i代表非this对象) "+i);
Thread.sleep(2000);
System.out.println("非静态方法7执行结束(i代表非this对象) "+i);
}
}
void fun11(Integer i) throws InterruptedException{
// String s = new String();
synchronized (s1) {
System.out.println("非静态方法11开始执行(非this对象) "+i);
Thread.sleep(2000);
System.out.println("非静态方法11执行结束(非this对象) "+i);
}
}
void fun8(Integer i) throws InterruptedException{
String s = new String();
synchronized (s) {
System.out.println("非静态方法8开始执行(非this对象) "+i);
Thread.sleep(2000);
System.out.println("非静态方法8执行结束(非this对象) "+i);
}
}
void fun10(Integer i) throws InterruptedException{
String s = new String();
synchronized (s) {
System.out.println("非静态方法10开始执行(非this对象) "+i);
Thread.sleep(2000);
System.out.println("非静态方法10执行结束(非this对象) "+i);
}
}
void fun9(int i) throws InterruptedException{
//synchronized (s1) {
System.out.println("未加锁方法9开始执行 " + i);
Thread.sleep(2000);
System.out.println("未加锁方法9执行结束 " + i);
//}
}
}
public class TestSuo {
public static void main(String[] args) {
Suo suo1 = new Suo();
Suo suo2 = new Suo();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
suo1.fun7(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
suo1.fun1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
// new Thread(new Runnable() {
//
// @Override
// public void run() {
//
//
// }
// }).start();
}
}
详细解释如下:
对象锁的两种实现方式:
类锁的两种实现方式:
synchronized方法与synchronized代码块的区别:synchronized method(){}与synchronized(this){}之间没有什么区别。只是前者便于阅读理解,而后者可以更精确的控制冲突限制访问区域(粒度更小),锁的范围没有变,锁住的时间变短了因而性能更好。
对象内所有加锁的非静态方法共用一把锁(即对象锁),一个加锁非静态方法执行,另一个加锁非静态方法就不能执行了,要等待持有锁的线程释放锁,不同对象之间的方法不互相作用。
类中的所有加锁的静态方法共用一把锁(即类锁),一个加锁的静态方法执行,同类另一个加锁静态方法就不能执行了,要等待持有锁的线程释放锁(对属于同一个类的两个对象的静态方法进行操作也会互斥执行)。
加对象锁和加类锁之间互不相干,执行时候没有影响。
加锁方法的执行不会影响类/对象中未加锁的方法的执行。
对于synchronized(非this对象):
在多个线程持有“对象监视器”为同一对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块里的代码。
在多个线程持有“对象监视器”不是同一对象,同一时间synchronized(非this对象)同步代码块里的代码异步执行,互不影响。
synchronized(非this对象)与synchronized方法异步执行,互不影响。
synchronized(a)与synchronized(b)方法异步执行,互不影响。