0%

同步锁

同步锁

除了使用synchronized来对代码块和方法进行同步外,jdk1.5之后还有一种Lock同步锁的方式进行同步

使用lock.lock()来进行加锁,使用lock.unlock()方法来释放锁

既然可以使用lock来代替synchronized,那么如何进行处理synchronized与wait()、notify()、notifyAll()的线程通信机制呢

在使用lock时使用Condition来进行线程通信

下面来使用两种方式来分别展示一下线程间通信

示例

使用Object的wait()、notify进行线程通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* wait()/notify()/notifyAll()是Object的方法
* 只能在synchronized方法或者代码块中使用,否则会报IllegalMonitorStateException异常
* 交替打印1-100
*/
public class TestThreadSignal {
public static void main(String[] args) {
PrintRunnable runnable = new PrintRunnable();
new Thread(runnable,"线程一").start();
new Thread(runnable,"线程二").start();
}
}

class PrintRunnable implements Runnable{
int num = 1;
@Override
public void run() {
while (true){
synchronized (this){
notify();// 唤醒wait的线程
if(num <= 100){
System.out.println(Thread.currentThread().getName() + "打印" + num++);
} else {
break;
}
try {
wait(); // 释放当前的锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}
}

使用condition的await()、signal()进行线程通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* 使用lock和condition来进行线程通信
* condition中的await()、signal()、signalAll()方法分别对应于Object中的wait()、notify()、notifyAll()方法
* 两个线程交替打印1-100
*/
public class TestThreadSignalForLock {
public static void main(String[] args) {
PrintRunnableForLock runnable = new PrintRunnableForLock();
new Thread(runnable,"线程一").start();
new Thread(runnable,"线程二").start();
}
}

class PrintRunnableForLock implements Runnable{
int num = 1;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
@Override
public void run() {
while (true){
try{
lock.lock();
condition.signal();// 唤醒线程
if(num <= 100){
System.out.println(Thread.currentThread().getName() + "打印" + num++);
} else {
break;
}
try {
condition.await(); // 释放当前的锁
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
lock.unlock();
}

}
}
}