初识Java并发编程

2022/1/15 22:05:12

本文主要是介绍初识Java并发编程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

    • 一、回顾线程基本内容
      • 1.基本概述
      • 2、创建线程
      • 3、常用方法
      • 4、线程状态
      • 5、多线程
      • 6、线程安全问题
      • 7、守护线程
      • 8、死锁
      • 9、线程通信
      • 10、wait() notify()notifyAll()
      • 11、sleep()和wait()
      • 12、生产者消费者问题
    • 二、并发编程
      • 1、并发编程是什么?
      • 2、多线程优点
      • 3、多线程带来的问题是什么?
      • 4、Java 内存模型(JMM)
        • (1)概述
        • (2)JVM 主内存与工作内存

一、回顾线程基本内容

1.基本概述

  • 程序:静态代码,安装在硬盘上的
  • 进程:运行中的程序,是操作系统分配内存空间的单位。
  • 线程:线程是进程中的一个最小的执行单元,是cpu调度单位,线程依赖于进程

2、创建线程

(1)线程类 继承Thread ,重写run()
(2)类 实现Runnable接口,创建Thread类的对象,为其分配任务
(3)类 实现Callable 接口,重写call() ,有返回值,可以抛出异常,创建Thread类的对象,为其分配任务

3、常用方法

run(),call(),start()设置名字,设置优先级

4、线程状态

start() 就绪状态, join() sleep()阻塞状态 ,yield()线程让步 运行状态
主动让出–>就绪状态
在这里插入图片描述

5、多线程

  1. 优点:程序如果同时有多个任务执行,需要多线程,多线程可以提高程序运行效率,提高cpu利用率
  2. 不足:对cpu内存的要求增加了,多线程同时访问同一个共享问题。

6、线程安全问题

多线程,且多个线程访问同一个共享数据??
解决方法:排队+锁
3. Synchronized:关键字 修饰方法,代码块,是隐式锁,自动加锁,自动释放锁
4. ReentrantLock:只能对某段代码加锁,是显示锁,手动添加,手动释放。

7、守护线程

用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守护线程的保姆:只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
守护线程的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC(垃圾回收器),它就是一个很称职的守护者。
用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了

注意:设置线程为守护线程必须在启动线程之前,否则会跑出一个IllegalThreadStateException异常。

8、死锁

不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃,自己需要的同步 资源,就形成了线程的死锁.
出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于,阻塞状态,无法继续。

9、线程通信

线程通讯指的是多个线程通过消息传递实现相互牵制,相互调度,即线程间的相互作用

10、wait() notify()notifyAll()

wait 一旦执行此方法,当前线程就会进入阻塞状态,并释放同步监视器。
notify一旦执行此方法 ,就会唤醒wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
notifyAll一旦执行此方法,就会唤醒所有被wait的线程。

11、sleep()和wait()

sleep()休眠指定的时间,时间到了后,会进入到就绪状态,不会释放锁
wait()让线程等待,必须需要通过notify()唤醒,等待时会释放锁

12、生产者消费者问题

生产者(Productor)将产品放在柜台(Counter),而消费者(Customer)从柜台处取走产品,生产者一次只能生产固定数量的产品(比如:1), 这时柜台中不能再放产品,此时生产者应停止生产等待消费者拿走产品,此时生产者唤醒消费者来取走产品,消费者拿走产品后,唤醒生产者,消费者开始等待。

二、并发编程

1、并发编程是什么?

  1. 并发:是在某一个时间段内,依次做好几件事情,一个一个的做,多个线程访问同一个资源,单核cpu不会出现问题,硬件cpu的功能逐渐强大,已经发展到多内核(4 8 12) 可以同时执行多个线程,这样就有可能多个线程同时执行。同时访问同一个共享数据,秒杀 抢购 …
    并发编程就是要让在多核,多线程情况下,也只能一次只有一个线程共享数据进行访问。
    我们线程已经可以通过加锁的方式实现,但是加锁并不是唯一的解决方案,还有其他方式来实现。本篇章我们要学习并发问题产生如何解决,学习新的方式解决,以及加锁内部的原理问题。
    多核cpu可以做到真正的并行执行,但是我们在某种场景就是要让程序并发执行。

  2. 并行:在一个时间节点,可以同时做多件事。
    在这里插入图片描述
    大家排队在一个咖啡机上接咖啡,交替执行,是并发;两台咖啡机上面接咖啡,
    是并行。

2、多线程优点

提高程序的性能,可以同时执行多个任务,榨取硬件的剩余价值。

3、多线程带来的问题是什么?

  1. 安全性(访问共享变量)
  2. 性能(cpu要切换线程)

4、Java 内存模型(JMM)

在这里插入图片描述

(1)概述

Java 内存模型(Java Memory Model,JMM)规范了 Java 虚拟机与计算机内存是如何协同工作的。Java 虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为 Java 内存模型。
Java 内存模型,用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的并发效果,JMM 规范了 Java 虚拟机与计算机内存是如何协同工作,规定了一个线程如何以及何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。
计算机在高速的 CPU 和相对低速的存储设备之间使用高速缓存,作为内存和处理器之间的缓冲。将运算需要使用到的数据复制到缓存中,让运算能快速运行,当运算结束后再从缓存同步回内存之中。
在多处理器的系统中(或者单处理器多核的系统),每个处理器内核都有自己的高速缓存,它们有共享同一主内存(Main Memory)。
当多个处理器的运算任务都涉及同一块主内存区域时,将可能导致各自的缓存数据不一致。

(2)JVM 主内存与工作内存

目标:
定义程序中各个变量的访问规则,即在虚拟机中将变量(线程共享的变量)存储到内存和从内存中取出变量这样底层细节。

  • 这里的工作内存是 JMM 的一个抽象概念,也叫本地内存,其存储了该线程以读 / 写共享变量的副本。
    就像每个处理器内核拥有私有的高速缓存,JMM 中每个线程拥有私有的本地内存。
    不同线程之间无法直接访问对方工作内存中的变量,线程间的通信一般有两种方式进行,一是通过消息传递,二是共享内存。Java 线程间的通信采用的是共享内存方式,线程、主内存和工作内存的交互关系如下图所示:
    这里所讲的主内存、工作内存与 Java 内存区域中的 Java 堆、栈、方法区等并不是同一个层次的内存划分,这两者基本上是没有关系的。
    在这里插入图片描述


这篇关于初识Java并发编程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程