zoukankan      html  css  js  c++  java
  • java的多线程学习,第五记

     死锁问题;

    public class DeadLock {
    
        //锁的嵌套 会出现死锁
        //1 尽量不要去写锁嵌套
        //2
    
        private static Object locka = new Object();
        private static Object lockb = new Object();
    
        public static void main(String[] args) {
            new DeadLock().deadLock();
        }
    
        private void deadLock() {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (locka){
                        try {
                            System.out.println(Thread.currentThread().getName()+"获取A锁 ing~!");
                            Thread.sleep(500);
                            System.out.println(Thread.currentThread().getName()+"睡眠 500ms!");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+"需要B锁!!!");
                        synchronized (lockb){
                            System.out.println(Thread.currentThread().getName()+"B锁中!!!");
                        }
                    }
                }
            },"thread1");
    
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lockb){
                        try {
                            System.out.println(Thread.currentThread().getName()+"获取B锁 ing~!");
                            Thread.sleep(500);
                            System.out.println(Thread.currentThread().getName()+"睡眠 400ms!");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+"需要A锁!!");
                        synchronized (locka){
                            System.out.println(Thread.currentThread().getName()+"A锁中!");
                        }
                    }
                }
            },"thread2");
    
            thread1.start();
            thread2.start();
        }
    
    }
    锁的嵌套 会出现死锁
    1 尽量不要去写锁嵌套
    2 锁嵌套的顺序
    3 引入超时机制
    显示锁ReentrantLock可重入的锁,我自己的锁可以多次进入。而sync是在jvm层面的。
    public class LockTest1 {
    
        Lock lock = new ReentrantLock();
    
        private static Object locka = new Object();
        private static Object lockb = new Object();
    
        public static void main(String[] args) {
            new LockTest1().deadLock();
        }
    
        private void deadLock() {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    getLock();
                }
            },"thread1");
    
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    getLock();
                }
            },"thread2");
    
            thread1.start();
            thread2.start();
        }
    
        public void getLock(){
            try{
                lock.lock();
                System.out.println(Thread.currentThread().getName()+"获取A锁 ing~!");
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName()+"睡眠 500ms!");
            }catch (InterruptedException e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
    显示锁ReentrantLock可重入的锁,我自己的锁可以多次进入。而sync是在jvm层面的。
    lock.lock()方法是上锁,然后还有在finally里面解锁。这个unlock()方法可能是会锁死的。
    或者,用trylock()方法。
    if(lock.tryLock(300, TimeUnit.MILLISECONDS)){
                        System.out.println(Thread.currentThread().getName()+"获取A锁 ing~!");
                        Thread.sleep(500);
                        System.out.println(Thread.currentThread().getName()+"睡眠 500ms!");
                    }else{
                        //记录日志
                        System.out.println("获取锁失败!");
                    }

    引入超时机制。还有中断锁lockInterruptibly()。

    如果某一线程A正在执行锁中的代码,另一个线程B正在等待获取该锁,可能由于等待时间过长,线程B不想等待了,想处理其他的事情,我们可以让它终端自己或者在别的线程中断它,这就是中断锁。

    公平锁,非公平锁。sync是非公平的,哪个线程先来都是随机的。公平锁式先来后到,fairLock。但是往往意味着效率低。

    public class ReentrantReadWriteLock
            implements ReadWriteLock, java.io.Serializable {

    ReentrantReadWriteLock并未实现Lock接口,它实现的是ReadWriteLock接口。

    读写锁对一个资源的访问,分成了两个锁,一个读锁和一个写锁。

    正因为有了读写锁,才使得多个线程之间的读操作不会发生冲突。

    在没有读写锁之前,是通过sync实现的。

    public class lockTest {
    
        private ReentrantReadWriteLock rw1 = new ReentrantReadWriteLock();
    
        public static void main(String[] args) {
            final lockTest test = new lockTest();
    
            new Thread(){
                public void run(){
                    test.get(Thread.currentThread());
                }
            }.start();
    
            new Thread(){
                public void run(){
                    test.get(Thread.currentThread());
                }
            }.start();
        }
    
        private synchronized void get(Thread currentThread) {
            long start = System.currentTimeMillis();
            while (System.currentTimeMillis() - start <= 1){
                System.out.println(currentThread.getName()+"正在进行读操作");
            }
            System.out.println(currentThread.getName()+"读操作完毕");
        }
    
    }

    而用读锁或者写锁的时候呢,

    public class lockTest {
    
        private ReentrantReadWriteLock rw1 = new ReentrantReadWriteLock();
    
        public static void main(String[] args) {
            final lockTest test = new lockTest();
    
            new Thread(){
                public void run(){
                    test.get(Thread.currentThread());
                }
            }.start();
    
            new Thread(){
                public void run(){
                    test.get(Thread.currentThread());
                }
            }.start();
        }
    
    //    private synchronized void get(Thread currentThread) {
    //        long start = System.currentTimeMillis();
    //        while (System.currentTimeMillis() - start <= 1){
    //            System.out.println(currentThread.getName()+"正在进行读操作");
    //        }
    //        System.out.println(currentThread.getName()+"读操作完毕");
    //    }
    
        private void get(Thread currentThread) {
            try{
                //获取一个读锁,再锁上
    //            rw1.readLock().lock();
                rw1.writeLock().lock();
                long start = System.currentTimeMillis();
                while (System.currentTimeMillis() - start <= 1){
                    System.out.println(currentThread.getName()+"正在进行读操作");
                }
                System.out.println(currentThread.getName()+"读操作完毕");
            }catch (Exception e){
                e.printStackTrace();
            }finally {
    //            rw1.readLock().unlock();
                rw1.writeLock().unlock();
            }
        }
    
    
    }

    可以用来提高某些集合的并发性能。当集合比较大,并且读比写频繁时,可以使用该类。

    乐观锁和悲观锁。这是数据库层面的锁。

    悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次拿数据的时候都会上锁。

    乐观锁:每次去拿数据的时候,都认为别人不会上锁,所以不会上锁。

     
     
  • 相关阅读:
    Codeforces899D Shovel Sale(思路)
    F
    Codeforces909D Colorful Points(缩点)
    LOD
    Instruments
    IO优化
    Unity JobSystem
    Android 设备指纹
    帧同步
    寻路
  • 原文地址:https://www.cnblogs.com/fuckingPangzi/p/10157225.html
Copyright © 2011-2022 走看看