多线程的按序打印

一.首先我们来了解一下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方法可以中断。


加锁是否公平:
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();

    }

}

 

你可能感兴趣的:(Synchorized,Lock)