美文网首页
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