Java基础之---并发(Concurrency)和多线程

本文深入探讨了Java并发编程的基础概念,包括进程与线程的区别、Java提供的并发支持机制,如线程池和java.util.concurrent包的使用。同时,文章详细解释了线程同步的重要性、同步方法及同步块的应用,以及如何避免线程冲突和内存一致性错误等问题。

Java提供并发主要通过两种方式:Java语言和Java类库,从5.0之后,Java又提供了高级的API:java.util.concurrent,来更好的支持并发

什么是并发?能够同时执行多项任务的能力叫并发。

进程和线程

进程和线程是两个基本的执行单位。进程是资源分配的基本单位,线程是处理机调度的基本单位

进程

进程是一个自包含的运行环境,它有一套完整的私有的资源。一个程序可由多个进程组成。,进程之间通过进程间通讯进行通信,操作系统提供进程间通讯的功能

线程

线程是轻量级的进程,创建线程需要的资源要比进程少。线程存在于进程中。

线程对象

两种实现并发程序的思路

  • 当需要执行异步任务时,直接控制线程的创建和管理(程序比较简单时),采用直接new 线程的方式
  • 抽象出程序的异步任务,将异步任务传递给Excutor,从而将线程的创建和管理从程序的其他部分中抽取出来(程序比较复杂时),采用线程池的方式

两种创建线程的方式

  • 实现Runnable接口,实现run方法(常用)
  • 继承Thread类,重写run方法(简单)

注意这两者的区别

sleep()

让当前的线程终止执行一段时间,这是线程主动发起的。

interupt()

设置线程的interupt flag.

join() 让当前线程等待被调用线程执行完毕或者等待一定的时间

同步

线程间通讯主要通过字段共享,这种通讯方式十分高效,但是会导致线程冲突和内存一致错误,同步正式防止这些错误的工具。

但是线程同步会引起线程竞争,当多个线程同时获取相同的资源时,会在这些线程间产生竞争,这会导致某个或者多个线程的执行速度减慢,甚至停止执行 。饥饿和活锁就是两种线程竞争的形式。

  1. 线程冲突

如果两个运行在不同线程里的操作由多个步骤组成,同时这两个操作作用于同样的数据,如果这两个操作有重叠的部分,那么这个时候线程冲突就形成了。在不同的条件下,由于重叠部分的不同,会有不同的结果,所以线程冲突的问题很难定位和解决。

2. 内存一致性错误

当两个线程对同一个数据获得的值不相同时,这时,内存一致性错误就发生了。解决的方式是,在这两个线程之间建立对这个相同数据的 happen-before关系,而建立这种关系的方式就是 同步。

3. 同步方法

当一个线程调用一个对象的时,会自动获得这个对象的内部锁,当方法返回时,会自动释放锁。当调用类的静态同步方法时,获取的是这个类的 .Class的对象的内部锁

会造成活锁

4.同步块

每一个对象都有一个内部锁,也叫监视器锁。在访问共享数据之前,线程需要获得这个内部锁,当访问结束时,释放这个锁。在没有释放锁之前,没有得到锁的线程只能阻塞。当释放内部锁时,这样就在后续访问的线程之间建立了happen-before关系

5. 可重入锁 一个线程不能获得其他线程获得的锁,但是它可以获得它已经拥有的锁

原子操作

活性问题

死锁

饥饿

活锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值