美文网首页
多线程并发基础巩固

多线程并发基础巩固

作者: 一只小安仔 | 来源:发表于2019-03-26 16:11 被阅读0次

多线程并发基础巩固

synchronized和volatile区别

1 synchronized 用于对对象加锁,其他线程便无法访问此对象的synchronized 方法。造成其他线程阻塞。直到拥有锁的对象释放锁,然后再去抢锁。synchronized 保证变量的可见性和原子性,所谓可见性:当一个线程对共享资源加锁时,其他线程依然持有对该变量可读的权限。所谓原子性:当一个线程对共享变量修改时,不会受到其他线程的干扰,也就是说,写操作必须执行时段,其他线程无法打断该操作。

2 volatile 使得共享资源的修改被其他线程知晓。及保证线程可以读到最近被修改的值。

jvm底层和场景分析:
这里先说jvm,jvm中所有程序在堆中分配内存。包括线程,每个线程在堆中存在线程私有的区域,这个区域叫TLAB(Thread Local Allocation Buffer)线程局部缓冲区,这块区域是线程私有,TLAB存在的意义是,当有线程需要操作共享区域的变量时,会把线程共享的资源拷贝(不是对象的引用)到自己的TLAB,直接对线程私有的资源读写操作,这样提高效率。可是如果对这个共有资源的变量修改没有通知其他需要操作此共享变量的线程。会导致其他线程使用到错误的数据(注意:线程并不是拷贝完共享资源后一直都不在去共享资源区同步资源,如果cpu空闲,会隔段时间去重新拷贝一下的。)。这里使用synchronized和volatile可以使得这样的情况不会发生。volatile主要实现方法是,在对共享变量修改时,通知其他拷贝该变量的线程重新拷贝,替换那个已经被修改的变量的值。当然synchronized也可以保证被读到的变量的最新状态。它主要使用到锁,锁机制效率比volatile低,synchronized修饰的共享变量不会被拷贝到线程私有的区域,而是让访问它的线程排队访问,当然这样做效率是低下的。
注:volatile放在变量前面,synchronized放在方法上,也可以放在一段代码块外。

下面的程序线程1永远不会结束,但解除对volatile后,线程1会在两秒后结束。

public class TestVolatile {

    private static /*volatile*/ boolean flag = true;

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" start");
                while (TestVolatile.flag){}
                System.out.println(Thread.currentThread().getName()+" end");
            }
        },"Threa1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+" start");
                TestVolatile.flag = false;
                System.out.println(Thread.currentThread().getName()+" end");
            }
        },"Threa2").start();

    }
}

sleep(),wait(),notify().notifyAll()区别

sleep()
该方法表示让当前正在执行的线程休眠一段时间,休眠时间通过参数传入。(休眠时间到了程序继续向下执行。)

wait()
让当前线程阻塞,并且释放锁(如果有获取锁)。意思是线程进入等待,直到有其他线程把它唤醒才继续执行。

notify()
唤醒一个阻塞的线程(具体会唤醒哪个阻塞的线程由cpu算法指定,java程序无法指定)。

notifyAll()
唤醒所有阻塞的线程。

相关文章

  • 多线程并发基础巩固

    多线程并发基础巩固 synchronized和volatile区别 1 synchronized 用于对对象加锁,...

  • android 多线程 — 线程的面试题和答案

    这里都是我从各个地方找来的资料,鸣谢: Java多线程干货系列—(一)Java多线程基础 JAVA多线程和并发基础...

  • 多线程并发知识精要

    学习多线程并发,要着重 “外练互斥,内修可见” ,这是掌握多线程、学习多线程并发的重要技术点。一、基础知识1、cu...

  • 多线程方法

    一. 基础并行多线程结构 二. 标准多线程方法,控制并发线程数,带线程锁

  • 架构师必备:阿里最新2020版多线程与高并发pdf

    多线程与高并发是架构中的基础,大家可以尝试回答下面的知识点,来看看你是否能够熟练掌握多线程与高并发 基础概念: 什...

  • 高并发Java

    高并发Java(1):前言 高并发Java(2):多线程基础 高并发Java(3):Java内存模型和线程安全 高...

  • 探秘Java并发模块:容器与工具类

    并发与多线程是每个人程序员都头疼的内容,幸好Java库所提供了丰富并发基础模块,这些多线程安全的模块作为并发工具类...

  • 带你搞懂Java多线程(一)

    什么是多线程 多线程也叫并发编程,那么在写多线程之前,我们先来了解一下并发编程的基础概念。①CPU核心数和线程数的...

  • Java多线程系列目录(共43篇)-转

    最近,在研究Java多线程的内容目录,将其内容逐步整理并发布。 (一) 基础篇 Java多线程系列--“基础篇”0...

  • 多线程基础

    1.关键术语和多线程基础介绍 关于多线程的基础知识请卡如下的文章: 高并发Java(1):前言 2.基础 参考:高...

网友评论

      本文标题:多线程并发基础巩固

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