Synchronized和ReentrantLock优缺点
synchronize关键字,优点:
1.不需要手动解锁,不会造成死锁
2.JDK1.8之后对其进行升级优化,性能和ReentrantLock相当
3.可重入锁
缺点:
1.不能终止锁
2.非公平锁
3.解锁后唤起任意阻塞线程
ReentrantLock类,优点:
1.可以通过设置超时时间终止锁
2.可以是公平锁,也可以是非公平锁
3.可重入锁
4.可根据condition唤醒符合条件的线程
缺点:
1.需要手动解锁,可能造成死锁
指定线程数量循环打印数字
使用synchronized关键字实现
public class LoopPrint {
public static volatile Integer index = 0;
public static final int THREAD_COUNT = 3;
public static final int MAX_COUNT = 15;
public static final Object OBJ = new Object();
public static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(new PrintThread(i), i + "").start();
}
}
}
class PrintThread implements Runnable {
private int index;
public PrintThread(int index) {
this.index = index;
}
@Override
public void run() {
while (true) {
synchronized (LoopPrint.OBJ) {
while (LoopPrint.index % LoopPrint.THREAD_COUNT != index) {
if (LoopPrint.index >= LoopPrint.MAX_COUNT) {
break;
}
try {
LoopPrint.OBJ.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (LoopPrint.index >= LoopPrint.MAX_COUNT) {
break;
}
System.out.println(Thread.currentThread().getName() + "线程执行: " + LoopPrint.index);
LoopPrint.index++;
LoopPrint.OBJ.notifyAll();
}
}
}
}
0线程执行: 0
1线程执行: 1
2线程执行: 2
0线程执行: 3
1线程执行: 4
2线程执行: 5
0线程执行: 6
1线程执行: 7
2线程执行: 8
0线程执行: 9
1线程执行: 10
2线程执行: 11
0线程执行: 12
1线程执行: 13
2线程执行: 14
使用ReentrantLock实现
public class LoopPrint {
public static volatile Integer index = 0;
public static final int THREAD_COUNT = 3;
public static final int MAX_COUNT = 15;
public static final Object OBJ = new Object();
public static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(new PrintLockThread(i), i + "").start();
}
}
}
class PrintLockThread implements Runnable {
private int index;
public PrintLockThread(int index) {
this.index = index;
}
@Override
public void run() {
while (true) {
try {
LoopPrint.lock.lock();
if (LoopPrint.index >= LoopPrint.MAX_COUNT) {
break;
}
if (LoopPrint.index % LoopPrint.THREAD_COUNT == index) {
System.out.println(Thread.currentThread().getName() + "线程执行: " + LoopPrint.index);
LoopPrint.index++;
}
} finally {
LoopPrint.lock.unlock();
}
}
}
}
0线程执行: 0
1线程执行: 1
2线程执行: 2
0线程执行: 3
1线程执行: 4
2线程执行: 5
0线程执行: 6
1线程执行: 7
2线程执行: 8
0线程执行: 9
1线程执行: 10
2线程执行: 11
0线程执行: 12
1线程执行: 13
2线程执行: 14
3个线程循环打印字母ABC
使用synchronized关键字实现
public class ThreadTest {
private static int number = 1;
public static void main(String[] args) {
new Thread(() -> {
while (true) {
synchronized (ThreadTest.class) {
while (number != 1) {
try {
ThreadTest.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number = 2;
System.out.println("A");
ThreadTest.class.notifyAll();
}
}
}).start();
new Thread(() -> {
while (true) {
synchronized (ThreadTest.class) {
while (number != 2) {
try {
ThreadTest.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number = 3;
System.out.println("B");
ThreadTest.class.notifyAll();
}
}
}).start();
new Thread(() -> {
while (true) {
synchronized (ThreadTest.class) {
while (number != 3) {
try {
ThreadTest.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number = 1;
System.out.println("C");
ThreadTest.class.notifyAll();
}
}
}).start();
}
}
使用ReentrantLock及Condition实现, 精准唤醒线程
public class ReentrantLockTest {
private static Lock lock = new ReentrantLock();
private static Condition cA = lock.newCondition();
private static Condition cB = lock.newCondition();
private static Condition cC = lock.newCondition();
private static int number = 1;
public static void main(String[] args) {
new Thread(() -> {
while (true) {
lock.lock();
try {
while (number != 1) {
cA.await();
}
System.out.println("A");
number = 2;
cB.signalAll();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}).start();
new Thread(() -> {
while (true) {
lock.lock();
try {
while (number != 2) {
cB.await();
}
System.out.println("B");
number = 3;
cC.signalAll();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}).start();
new Thread(() -> {
while (true) {
lock.lock();
try {
while (number != 3) {
cC.await();
}
System.out.println("C");
number = 1;
cA.signalAll();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}).start();
}
}
运行结果
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
...