Java多线程同步互斥执行某个方法或某段代码

1.      使用synchronized关键字
(1)    同步方法
修饰对象实例方法
e.g.
class A{
private final byte[] INSTANCE_LOCK=new byte[0];
synchronized void instanceMethod(){
}
}
A a1 = new A();
A a2 = new A();
A a3=new A();


当多个线程调用a的方法instanceMethod时,同一时刻只有一个线程能执行
线程1执行a1. instanceMethod()
线程2执行a1. instanceMethod()
线程3执行a2. instanceMethod()
线程4执行a2. instanceMethod()
线程5执行a3. instanceMethod()
线程6执行a3. instanceMethod()
同一时刻线程1、2只有一个线程能执行a1. instanceMethod()
同一时刻线程3、4只有一个线程能执行a2. instanceMethod()
同一时刻线程5、6只有一个线程能执行a3. instanceMethod()
线程1(或2 )、3(或4)、5(或6)并不同步互斥
synchronized void instanceMethod(){
}
//等价于
void instanceMethod(){
synchronized(this){
}
}


对象锁为当前的对象实例,如a1,a2,a3等
也可等价于
void instanceMethod(){
sysnchronized(INSTANCE_LOCK){
}
}
 
//修饰类方法(静态方法)
//e.g.
class B{
private static final byte[] CLASS_LOCK=new byte[0];
synchronized static void classMethod(){
}
}

当多个线程调用B的静态方法classMethod(),同一时刻只有一个线程能执行
例如
B b1 = new B();
B b2 = new B();
B b3 = new B();
线程1执行b1. classMethod()或B.classMehoth()
线程2执行b2.classMethod()或B.classMehoth()
线程3执行b3.classMehtoed()或B.classMehoth()
同一时刻线程1、2、3只有一个线程能执行B.classMehoth()
synchronized static void classMethod(){
}
//等价于
void classMethod(){
synchronized (B.class)
}
}

对象锁为当前的对象所属的类
也等价于
void classMethon(){
Synchronized(CLASS_LOCK){
}
}

注:获取对象锁之后便可以进入方法或代码块,当方法或代码执行完对象锁自动释放
(2)    同步代码块
Object lock;
synchronize(lock){
//……
}

拥有对象锁lock之后便可以进入代码块,代码执行完对象锁lock自动释放

2.      wait()、notify()
Object lock;
1.lock.wait() 释放对象锁,并让当前线程(执行lock.wait()的线程)等待直到另一个线程调用lock.notify()
2.lock.notify() 唤醒其他线程(执行lock.wait()的线程)

使用wait()和notify()时,当前线程应该拥有对象锁
(the owner of this object's monitor)
synchronized (lock){
// 拥有对象锁进入代码块
// do a 
lock.wait(); // 手动释放对象锁(让其他线程可以拥有对象锁),等待直到其他线程通知
// 收到通知后do b
}
 
synchronized(lock){
//拥有对象锁do c
Lock.notify();// 通知等待线程执行(The awakenedthread will not be able to proceed until the current thread relinquishes thelock on this object)
// 继续do d
// 自动释放对象锁(唤醒的线程可以执行了)
}

你可能感兴趣的:(java,多线程)