首页IT科技java并发编程从入门到精通(JUC并发编程)

java并发编程从入门到精通(JUC并发编程)

时间2025-05-03 20:46:47分类IT科技浏览3274
导读:什么是JUC JDK1.5出现的,用来处理线程的工具包...

什么是JUC

JDK1.5出现的           ,用来处理线程的工具包

进程与线程

进程:指在系统中正在运行的一个应用程序;程序一旦运行就是进程;进程一 -资源分配的最小单位           。

线程:系统分配处理器时间资源的基本单元                 ,或者说进程之内独立执行的一个单元执行流                 。线程一程序执行的最小单位      。

线程的状态

NEW(新建)           、RUNNABLE(可运行)                 、BLOCKED(阻塞)      、WAITING(等待)           、TIMED_WAITING(定时等待)                 、TERMINATED(终止)

wait和sleep区别

①sleep是Thread的静态方法      ,wait是Object的方法任何对象实例都能调用

②sleep不会释放锁也不会占用锁           。wait会释放锁           ,但调用前提是当前线程有锁

③都可以被interrupted方法中断

并发与并行

解释一:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生                 。

解释二:并行是在不同实体上的多个事件                 ,并发是在同一实体上的多个事件      。

解释三:在一台处理器上“同时           ”处理多个任务      ,在多台处理器上同时处理多个任务     。

并发:指的是多个事情     ,在同一时间段内同时发生了                 ,多个任务之间是互相抢占资源的                 。

并行:指的是多个事情           ,在同一时间点上同时发生了     ,多个任务之间是不互相抢占资源的           。

只有在多CPU的情况中                 ,才会发生并行     。否则           ,看似同时发生的事情,其实都是并发执行的                 。

Lock 和 Synchronized

①Synchronized是Java关键字                 ,是同步锁           。可修饰代码块      、方法(不被子类继承)     、静态方法                 、类

②发生异常会自动释放锁                 ,如果被阻塞会一直无限期等待

③synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现为以下3种形式                 。

对于普通同步方法,锁是当前实例对象                 。

对于静态同步方法           ,锁是当前类的class对象。

对于同步方法块                 ,锁是Synchonized括号里配置的对象           。

①Lock是一个接口      ,通过这个接口的实现类可以实现同步访问           ,必须要用户手动释放锁                 ,如果不释放会发生死锁                 。

②Lock可以让等待锁的线程响应中断      ,Synchronized却不行     ,等待线程会一直等待下去

③Lock可以知道有没有成功获取锁

④Lock可以提高多个线程进行读操作的效率

线程间的通信 等待/通知

①关键字Synchronized通过wait()/notify()两个方法实现等待/通知      。

②Lock锁的newCondition()方法返回Condition对象                 ,Condition类也可以实现等待/通知           。

区别:

notify()随机唤醒           ,使用Condition可以选择性通知     ,condition比较常用的两个方法:

• await()会使当前线程等待,同时会释放锁,当其他线程调用 signal()时,线程会重新获得锁并继续执行                 。

• signal()用于唤醒一个等待的线程      。

Lock 和 ReadWriteLock 接口

Lock的实现类ReentrantLock可重入锁

ReadWriteLock的实现类ReentrantReadWriteLock可重入读写锁                 ,读写锁分开           ,从而使得线程可以同时进行读操作

注意:

有一个线程占用读锁,其他线程申请写锁会等待读锁释放

有一个线程占用写锁                 ,其它线程申请写锁或读锁会一直等待释放写锁

集合的线程安全

Vector

所有的方法                 ,都是通过synchronized修饰,方法锁           ,实际也是对象锁                 ,安全

Collections

Collections 提供了方法 synchronizedList 保证 list 是同步线程安全的

都是通过mutex对象加锁      ,一样           ,效率和Vector一样低

CopyOnWriteArrayList(重点)

写时复制的方法                 ,来控制的读写分离     。但是存在的问题就是      ,会出现脏读的现象

Callable&Future 接口

创建线程的方法     ,一种是通过Threa类                 ,另一种使用Runnable创建线程           ,无法使线程返回结果     ,而Callable可以                 。

Callable接口

Runnable只需要实现不返回任何内容的run()方法                 ,对于Callable需要实现完成时返回结果的call()方法           。

call()方法可以引发异常           ,而run()不能

new Thread(Runnable r)不能直接替换Runnable,因为Thread类构造方法没有Callable

Future接口 实现类 FutureTask

当 call()方法完成时                 ,结果必须存储在主线程已知的对象中                 ,以便主线程可以知道该线程返回的结果     。为此,可以使用 Future 对象                 。

public boolean cancel(boolean mayInterrupt):用于停止任务 public Object get() 抛出 InterruptedException           ,ExecutionException:用于获取任务的结果           。 public boolean isDone():如果任务完成                 ,则返回 true      ,否则返回 false

在主线程中需要执行比较耗时的操作时           ,但又不想阻塞主线程时                 ,可以把这些作业交给 Future 对象在后台完成

一般 FutureTask 多用于耗时的计算      ,主线程可以在完成自己的任务后     ,再去获取结果

get 方法而获取结果只有在计算完成时获取                 ,否则会一直阻塞直到任务转入完成状态           ,然后会返回结果或者抛出异常 public class CallableDemo { static class Mythread1 implements Runnable{ @Override public void run() { try { System.out.println(Thread.currentThread().getName()+"线程进入了run方法"); } catch (Exception e) { e.printStackTrace(); } } } static class Mythread2 implements Callable{ @Override public Long call() throws Exception { try { System.out.println(Thread.currentThread().getName()+"线程进入了call方法,开始准备睡觉"); Thread.sleep(1000); System.out.println(Thread.currentThread().getName()+"睡醒了"); } catch (InterruptedException e) { e.printStackTrace(); } return System.currentTimeMillis(); } } public static void main(String[] args) throws Exception { Runnable runnable = new Mythread1(); Callable callable = new Mythread2(); FutureTask<Long> futureTask = new FutureTask<Long>(callable); //线程一 new Thread(runnable,"线程一").start(); //线程二 new Thread(futureTask,"线程二").start(); for (int i = 0; i < 10; i++) { Long result = futureTask.get(); // 阻塞等待计算结果 System.out.println(result); } } }

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
手机开启无线显示打不开怎么回事(不用USB,通过adb无线调试安卓手机页面) ios主题安卓下载(Android ViewPager2 + TabLayout + BottomNavigationView)