1.synchronized

synchronized关键字是一个悲观锁,可以用于变量,方法及类。

很多人会将synchronized和volatile做比较,个人理解volatile其实就是将一个变量公开话,一个线程修改,任何线程可同步见到。

volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取。

2.ReentrantLock 

ReentrantLock 与 synchronized 很相似,也是一种互斥锁(lock),只是ReentrantLock 相对 synchronized 而言还是增加了一些高级功能.

等待可中断:lock.lockInterruptibly();//获取响应中断锁

public class lockReentrantLock {
        private Lock lock = new ReentrantLock();
        public  static  void main(String[] args) {
            final lockReentrantLock buff = new lockReentrantLock();
            final Thread writer = new Thread(new Runnable() {
                public void run() {
                    try {
                        buff.write();
                    } catch (InterruptedException e) {
                        System.out.println("写中断异常");
                    }
                    System.out.println("写结束");
                }
            });
            final Thread reader = new Thread(new Runnable() {
                public void run() {
                    try {
                        buff.reader();
                    } catch (InterruptedException e) {
                        System.out.println("我不想读了");
                    }
                    System.out.println("读结束"); }
            });
            writer.start();
            reader.start();
            //  中断读操作
            new Thread(new Runnable() {
                public void run() {
                    long start = System.currentTimeMillis();
                    for (;;) {
                        if (System.currentTimeMillis()
                                - start > 5000) {
                            System.out.println("不等了,尝试中断");
                            reader.interrupt();  //此处中断读操作
                            break; } } } }).start();
        }

        public void reader() throws  InterruptedException{
            lock.lockInterruptibly();
            System.out.println("开始读数据");
            lock.unlock();      }
        public void write() throws  InterruptedException{
            lock.lock();
            long starttime=System.currentTimeMillis() ;
            System.out.println("开始写数据");
            for(;;)
            {
                if(System.currentTimeMillis() -starttime>10000)
                {
                    System.out.println("终于写数据结束了");
                    break;  }
            }
            lock.unlock();
        }
}
输出结果

可实现公平锁:(公平锁)多线程获取锁的顺序是按照线程加锁的顺序来分配的。(非公平锁)都是随机,可能造成某些线程一直无法运行。

公平锁: Lock lock = new ReentrantLock(true); 非公平锁: Lock lock = new ReentrantLock(false);

ReentrantReadWriteLock类
public static void main(String[] args){
    final  ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    Thread reader=new Thread(new Runnable() {
        public void run() {
            try {
                try {
                    lock.readLock().lock();
                    System.out.println(Thread.currentThread().getName() + " 获得读锁,当前时间" + System.currentTimeMillis());
                    Thread.sleep(5000);
                } finally {
                    lock.readLock().unlock();
                }
            }catch ( Exception e)
            { }      }
    });
    reader.setName("readerOne");
    reader.start();
    Thread reader1=new Thread(new Runnable() {
        public void run() {
            try {
                try {
                    lock.readLock().lock();
                    System.out.println(Thread.currentThread().getName() + " 获得读锁,当前时间" + System.currentTimeMillis());
                } finally {
                    lock.readLock().unlock();
                }
            }catch ( Exception e)
            { }}
    });
    reader1.setName("readerTwo");
    reader1.start();
}

输出

将readLock改成writeLock 可以看出读和读是共享得  读写互斥 写写互斥。

 

锁可以绑定多个条件:ReentrantLock 对象可以同时绑定多个 Condition 对象(名曰:条件变量或条件队列),而在 synchronized 中,锁对象的 wait()和 notify()或 notifyAll()方法可以实现一个隐含条件,但如果要和多于一个的条件关联的时候,就不得不额外地添加一个锁,而 ReentrantLock 则无需这么做,只需要多次调用 newCondition()方法即可。而且我们还可以通过绑定 Condition 对象来判断当前线程通知的是哪些线程(即与 Condition 对象绑定在一起的其他线程)Condition是Java提供了来实现等待/通知的类,Condition类还提供比wait/notify更丰富的功能,Condition对象是由lock对象所创建的。但是同一个锁可以创建多个Condition的对象,即创建多个对象监视器。这样的好处就是可以指定唤醒线程。notify唤醒的线程是随机唤醒一个

    public static void main(String[] args){
        final Lock lock = new ReentrantLock();
        final Condition condition=lock.newCondition();
        Thread reader=new Thread(new Runnable() {
            public void run() {
                try {
                    try {
                        lock.lock();
                        System.out.println(Thread.currentThread().getName() + "await 开始执行时间" + System.currentTimeMillis());
                        condition.await();
                        System.out.println(Thread.currentThread().getName() + "await 结束时间aaa" + System.currentTimeMillis());
                    } finally {
                        lock.unlock();
                    }
                }catch ( Exception e)
                { }      }
        });
        reader.setName("A");
        reader.start();
        Thread b=new Thread(new Runnable() {
            public void run() {
                try {
                    try {
                        lock.lock();
                        System.out.println(Thread.currentThread().getName() + "await 开始执行时间" + System.currentTimeMillis());
//                        condition.awaitUntil();
                        System.out.println(Thread.currentThread().getName() + "await 结束时间bbb " + System.currentTimeMillis());
                    } finally {
                        lock.unlock();
                    }
                }catch ( Exception e)
                { }      }
        });
        b.setName("B");
        b.start();
        Thread reader2=new Thread(new Runnable() {
            public void run() {
                try {
                    try {
                        lock.lock();
                        System.out.println(Thread.currentThread().getName() + "signal 开始执行时间" + System.currentTimeMillis());
                        condition.signalAll(); //如果是signal的话 只能唤醒一个线程
                        System.out.println(Thread.currentThread().getName() + "signal 结束时间" + System.currentTimeMillis());
                    } finally {
                        lock.unlock();
                    }
                }catch ( Exception e)
                { }      }
        });
        reader2.setName("C");
        reader2.start();

 

输出:

Aawait 开始执行时间1603283537973
Bawait 开始执行时间1603283537974
Csignal 开始执行时间1603283537977
Csignal 结束时间1603283537977
Aawait 结束时间aaa1603283537977
Bawait 结束时间bbb 1603283537977
 

参考文章:

https://www.cnblogs.com/qifengshi/p/6354890.html

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值