Synchorized|多线程的按序打印

一.首先我们来了解一下Synchroized和Loke的区别

原始构成:
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唤醒的方式是要么随机唤醒唤醒一个要么全部唤醒。
基于Lock可以绑定多个Condation以及Condation的精确唤醒,我们可以使用这个属性来进行多线程之间的按序打印相比使用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(); }}


    推荐阅读