sychronized和Lock区别

两者区别

 Sychronized  Lock
类型java的一个关键字,也就是说java语言内置的特性,wait 、notify、notifyAlljava.util.concurrent.locks包下常用的类,可以使用Condition进行线程之间的调度,
锁的释放会自动释放锁(1.执行完同步代码块会释放锁,2线程执行过程中发生异常会释放锁,不会出现死锁)需要在finally中手工释放lock.unlock(),否则容易造成线程死锁,使用时记住try catch
使用特性可重入\不可中断\非公平可重入\可中断(interrupt)\可公平(也可非公平)
获取锁的状态不能知道有没有获取锁

可以通过trylock来知晓是否获取到了锁

 Sychronized原理

采用的是CPU悲观锁机制,线程获得的是独占锁,其他线程只能依靠阻塞来等待线程释放锁

1.5之前是低效的,1.6之后优化可以适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等

 

Lock原理

采用的乐观锁机制.  乐观锁实现的机制就是CAS操作(Compare and Swap) 判断值是否与预期值

 

 

三个线程循环打印abc

java多线程编程之连续打印abc的几种解法 - 平凡希 - 博客园 (cnblogs.com)

public class Lockprinter {
    //状态变量
    private volatile int state = 0;


    private class Printer implements Runnable {
        private static final int PRINT_COUNT = 10;

        //打印锁
        private final Object printLock;
        //打印标志位 和state关联
        private final int printFlag;
        //后继线程的打印标志位  state变量相关
        private final int nextPrintFlag;
        //该线程的打印字符
        private final char printChar;

        public Printer(Object printLock, int printFlag, int nextPrintFlag, char printChar) {
            super();
            this.printLock = printLock;
            this.printFlag = printFlag;
            this.nextPrintFlag = nextPrintFlag;
            this.printChar = printChar;

        }


        @override
        public void run() {
//获取打印锁  进入临界区
            synchronized (printLock) {
                //连续打印PRINT_COUNT
                for (int i = 0; i < PRINT_COUNT; i++) {
                    //循环检验标志位,每次都阻塞然后等待唤醒
                    while (state != printFlag) {
                        try {
                            printLock.wait();
                        } catch (InterruptedException e) {
                            return;
                        }
                    }
                    //打印字符
                    System.out.println(printChar);
                    //设置状态变量为下一个线程的标志位
                    state = nextPrintFlag;
                    //注意要notifyAll,不然会死锁,因为notify只通知一个
                    //但是同时等待的是两个, 如果唤醒的是不正确的那个就会没人唤醒,死锁了
                    printLock.notifyAll();
                }
            }
        }
    }

    public  void test() throws InterruptedException{
        //锁
        Object lock = new Object();
        //打印a的线程
        Thread threadA = new Thread(new Printer(lock,0,1,'A'));
        //打印b的线程
        Thread threadB = new Thread(new Printer(lock,1,2,'B'));
        //打印c的线程
        Thread threadC = new Thread(new Printer(lock,2,0,'C'));
        //一次启动ABC 线程
        threadA.start();
        Thread.sleep(100);
        threadB.start();
        Thread.sleep(100);
        threadC.start();
    }

    public static void main(String[] args) throws InterruptedException {

        Lockprinter print = new Lockprinter();
        print.test();
    }

}






}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值