第一种方法:采用公平锁实现
思路及其简单:
- A线程拿到锁,执行代码
- B线程拿到锁,执行代码
- A线程拿到锁,执行代码
- ......
public class FairLockDemo {
public static void main(String[] args) {
Runnable target = new Runnable(){
int i = 10;
// 利用公平锁
private ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
while (i >= 0) {
try{
lock.lock();
if(i % 2 == 0){
System.out.println("A");
}else {
System.out.println("B");
}
i--;
}finally{
lock.unlock();
}
}
}
};
Thread t1 = new Thread(target, "thread-1");
Thread t2 = new Thread(target, "thread-2");
t1.start();
t2.start();
}
}
第二种方法:采用synchronized对象锁 + wait + notify实现
思路比较复杂,值得细细揣摩:
- 关键点:每个线程都有获得锁的权利
- 1、满足if条件的,wait等待释放锁
- 2、不满足if条件的,执行业务代码
public class TestThead {
// 对象锁
private static Object obj = new Object();
private static volatile int num = 10;
public static void main(String[] args) {
new Thread(new Runnable() { // 匿名内部类
@Override
public void run() {
synchronized (obj) {
while(num > 0){
if(num % 2 == 0){
try {
obj.wait(); // 释放锁进入等待队列(等待池),线程2获取到对象锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num--;
if(num >= 0){
System.out.println("B");
}
obj.notify(); // 唤醒等待队列中线程2进入锁池竞争对象锁
}
}
}
}, "thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (obj) {
while(num > 0){
if(num % 2 != 0){
try {
obj.wait(); // 释放锁进入等待队列(等待池),线程1获取到对象锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num--;
if(num >= 0){
System.out.println("A");
}
obj.notify(); // 唤醒等待队列中线程1进入锁池竞争对象锁
}
}
}
}, "thread2").start();
}
}
3、采用Lock和Condition实现
思路:
- 其实和上面的思路差不多
- 只不过上面用了同一个对象锁,思考起来比较麻烦
- 这里采用了两个锁,轮流开闭,思考起来很方便
public class LockCond {
private static volatile int count = 10;
private static Lock lock = new ReentrantLock();
public static void main(String[] args) {
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
new Thread(()->{
while(count > 0) {
lock.lock();
try {
if(count % 2 == 0) {
System.out.println("A");
c1.await();
}
//唤醒线程2
c2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
count--;
lock.unlock();
}
}
}) .start();
new Thread(()->{
while(count > 0) {
lock.lock();
try {
if(count % 2 == 1) {
System.out.println("B");
c2.await();
}
//唤醒线程1
c1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
count--;
lock.unlock();
}
}
}) .start();
}
}