一.首先我们来了解一下Synchroized和Loke的区别
原始构成:基于Lock可以绑定多个Condation以及Condation的精确唤醒,我们可以使用这个属性来进行多线程之间的按序打印相比使用Synchorized方便了许多:
1.Synchroized:属于jvm层面它是java的关键字
底层是monitor对象:
monitorenter(进入)
monitorexit:(出来)
2.synchronized底层是通过monitor对象来完成,其实wait以及notify方法也依赖于monitor对象,只有在同步快或者方法中wait或者notify方法才能被使用。
3.lock是api层面知识是java的一个类。
使用方法:
1.synchronized不需要用户自动释放锁对象,由系统自动退出,有异常和正常两种退出方式。
2.lock则需要用户手动去释放锁对象,如果没有释放所对象的话,就可能会导致死锁问题。需要使用lock和unlock来加锁和
释放锁。
等待是否可以中断:
1.synchronized不可中断,除非抛出异常或者程序的正常的退出。
2.ReentrantLock可以中断:
设置超时方法tryLock(long timeOut,TimeUnit unit)。
lockinteruptibly()放入代码块汇总,调用interrupt方法可以中断。
【Synchorized|多线程的按序打印】
加锁是否公平:
1.synchorized是一个可重入的非公平锁。
2.ReentrantLock两者都是可以的,默认是非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁。
锁绑定多个条件的Condation:
1.ReentrantLock用来实现分组唤醒需要唤醒的线程们,可以精确的唤醒,而不是像synchorized要么随机唤醒唤醒一个要么全部唤醒,synchorized唤醒的方式是要么随机唤醒唤醒一个要么全部唤醒。
题目描述:假设有三个线程ABC,A线程打印五次,接下来B线程打印十次,C线程打印15此,紧接着,A线程打印五次,接下来B线程打印十次,C线程打印15.
代码实现:
package FaceToFace;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareResource{
private int num=1;
//num=1表示A线程;
num=2表示B线程;
num=3表示C线程
private Lock lock=new ReentrantLock();
private Condition c1=lock.newCondition();
private Condition c2=lock.newCondition();
private Condition c3=lock.newCondition();
public void print5(){lock.lock();
try {
while (num!=1){
c1.await();
}
for (int i=1;
i<=5;
i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
//通知B线程
num=2;
c2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(){
lock.lock();
try {
while (num!=2){
c2.await();
}
for (int i=1;
i<=10;
i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}//通知C线程
num=3;
c3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}public void print15(){
lock.lock();
try {
while (num!=3){
c3.await();
}
for (int i=1;
i<=15;
i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}//再次唤醒A线程
num=1;
c1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class SynAndReentranLockDemo {public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(()->{
for(int i=1;
i<=10;
i++){
shareResource.print5();
}
},"A").start();
new Thread(()->{
for(int i=1;
i<=10;
i++){
shareResource.print10();
}},"B").start();
new Thread(()->{
for(int i=1;
i<=10;
i++){
shareResource.print15();
}},"C").start();
}}