美文网首页
java高并发01:synchronizr

java高并发01:synchronizr

作者: 城南码农 | 来源:发表于2018-02-02 16:53 被阅读0次

    说了无数次高并发,每次都是断断续续。今天打算好好来学习记录一下。
    高并发三个知识点:同步器synchronizer / 同步容器 / 线程池
    课程地址:http://www.sxt.cn/concurrence/4-8.html

    synchronized关键字
    • .对象o的锁
    Object o = new Object();
     synchronized(o){
       ...
     }
    
    • .this 锁定当前对象 当前对象指谁?看下验证代码
    synchronized(this){
        
    }
    

    动手实验:结果是锁定方法所在类的对象(本类对象调用本类方法)

    public class MyService {
        public void myMethod() {
            /**
             * 验证this锁定的是那个对象
             * 经过实验,this,锁定的是方法所在类的对象(即:MyService对象)
             * 1.web中要锁定的对象是否为单例
             * 2.同类中的其他synchronized(this)修饰符也会被锁定
             */
            synchronized (this) {
                for (int i = 0; i < 100; i++) {
                    System.out.println("I : " + i + " thread Name:{}" + Thread.currentThread().getName());
                }
            }
        }
    }
    public class MyThreadA implements Runnable {
        MyService sev;
    
        MyThreadA(MyService sev) {
            this.sev = sev;
        }
    
        @Override
        public void run() {
            sev.myMethod();
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyService sev = new MyService();
            Thread t1 = new Thread(new MyThreadA(sev));
            t1.start();
    
            MyService sev2 = new MyService();
            //Thread t2 = new Thread(new MyThreadB(sev2));
          // t1 和 t2 才会加共同的锁
            Thread t2 = new Thread(new MyThreadB(sev));
            t2.start();
        }
    }
    

    小结:对象锁锁定的对象属性变化时,对锁定对象无影响。但是对象发生变化时锁就会失效。
    对象锁锁定的是堆方法中的对象实体,并非栈内存的对象引用。

    • 修饰普通方法 (对象锁)
    // 同样锁定是本类对象
    public synchronized void  get(){
    }
    
    • 修饰静态方法 (类锁)
    // 锁定的是T.class 也就是类级别的锁
    public synchronized static void set(){
    }
    

    小结:synchronized保证了原子性和可见性

    volatile关键字

    内存可见性,禁止重排序
    保证线程对vloatile修饰变量的操作及时刷回主内存,并且作废其他线程缓存区的缓存。(主要是后面步骤)

    AtomXXX

    原子类,用于计数。

    不能以字符串常量加锁
    String s1="111";
    String s2="111";
    s1&s2是同一个对象的锁
    
    wait & notify
    Object lock = new Object();
    synchronized(lock){
    }
    lock.wait();//让  获得lock锁的当前线程  等待,释放lock锁
    lock.notify();// 启动正在对象上等待的线程  或者notifyAll() 但是不会释放锁
    
    CountDownLatch
    //加上了2道门栅
    CountDownLatch latch = new CountDownLatch(2); 
    latch.await(); // 必须等所有的门栅释放完完才会唤醒
    latch.countDown();// 调用一次释放一道门栅
    
    

    Reentrantlock 显示锁
       Lock lock = new ReentrantLock();
    // 必须手动加锁和释放锁
    lock.lock();
    lock.unlock();
    

    可以使用tryLock() 判断是否能获取锁。返回boolean类型值做不同的业务处理。
    概念解释:
    公共锁:先来先得。线程A释放了锁,其他等待锁的线程里谁最先来等待的,谁获取这个锁。
    Lock lock = new ReentrantLock(true);//表示公平锁
    非公平锁:随机分配。线程A释放了锁,其他等待锁的线程随机获取这个锁。

    ThreadLocal

    线程局部变量,每个线程自己保存一份

    相关文章

      网友评论

          本文标题:java高并发01:synchronizr

          本文链接:https://www.haomeiwen.com/subject/nohhzxtx.html