dijiuzu

 

20220804 第一组 于芮 多线程基础(第二十四天)

 

小白成长记——第二十四天

   经历了三天的学习终于完成了多线程基础的学习,又是被打击的一天,好像听懂了,好像又没听懂,就像一团浆糊,果然是比较难啃的一块硬骨头,但是我会继续努力,早晚可以看懂的,加油啊!!!来看一下今天的学习笔记吧!!

 

locksupport-轻量级锁工具类(线程阻塞的工具类--所有方法都是静态方法,可以让线程在任意位置阻塞,有唤醒的方法)
park:停车(停止)
UNpark:启动
与wait和notify的区别
1.park不需要回去某个对象的锁(不释放锁)
2.因为中断park不会抛出interrupted异常,需要在park之后自行判断中断状态,然后做出额外的处理
 
总结
1.park和UNpark可以实现wait呢notify的功能,但是并不能交叉使用
2.park和UNpark不会出现死锁
3.blocker的作用可以看到阻塞对象的信息
 
lock锁(接口)
实现类
reentrantlock可重入锁,实现了lock接口
 
synchronize和lock的区别
1.lock是一个接口,synchronize是一个关键字,是由底层C语言实现的
2.synchronize发生异常时,会自动释放线程占用的锁不会发生死锁
lock发生异常,若没有主动释放,极有可能占用资源不放手,需要在finally中手动释放资源
3.lock可以让等带的线程相应中断,使用synchronize只会让等待的线程一直的等待,不能响应中断
4.lock可以提高多个线程进行读操作的效率
 
以下功能是synchronize不具备的
1.ReentrantReadWriteLock
对于一个应用而言,一般情况下,读操作远远比写的操作,如果仅仅是读的操作没有写的操作,
数据又是线程安全,读写锁给我们提供了一种锁,读的时候可以很多线程一起读,但是不能有线程写
写是独占的,当有线程在执行写的操作,其他线程既不能读,也不能写
在某些场景下能极大的提升效率
 
lock锁的原理cas和aqs
synchronize是由C语言实现的,只能作为关键字来使用,
java提高了一些并发的编程的包,底层的实现原理cas和aqs
 
并发编程的三大特性
1.原子性
院子操作可以是一个步骤,也可以是多个步骤,但是顺序不能乱,
也不可以被切割只执行其中的一部分,将整个操作视为一个整体
原子性不仅仅是多行代码,也可能是多条指令
2.可见性
3.有序性
synchronize lock:可以保证原子性,可见性
CAS:比较并交换,就是给一个元素赋值的时候,先看看内存里的那个值到底变没变
AQS:抽象队列同步器,用来解决线程同步执行的问题。他是一个双向链表
 
JUC并发编程包
1.原子类Atomic
基本类型
AtomicInteger:整型原子类
AtomicLong:长整型原子类
AtomicBoolean:布尔型原子类
数组类型
AtomiclongArray:长整型数组原子类
AtomicIntegerArray:整型数组原子类
AtomicReference<V>:引用数据类型原子类
 
线程池
为什么使用线程池
1.降低资源消耗
通过重复利用自己创建的线程,降低创建和销毁造成的资源消耗
2.提高响应速度
当线程到达时,任务可以不需要等到线程创建就能立即执行
3.提高线程的可管理性,线程比较稀缺的资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调配和监控
 
JDK自带的四种线程池
1.newCachedThreadPoo创建一个可缓存的线程池,如果线程池长度超过处理需要,可以灵活回收空闲线程
2.newFixedThreadPool创建一个定长的线程,可以控制线程最大并发数,超出的线程会在队列中等待
3.newScheduledThreadPool创建一个定长的线程池,支持周期性和定时任务执行
4.newSingleThreadExecutor创建一个单线程化的线程池,只会用唯一的工作线程来执行任务,保证所有的任务按照指定顺序执行
这四种线程池的初始化,都调用了同一个构造器
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数的意义
corePoolSize线程池里线程的数量,核心线程池大小
maximumPoolSize指定了线程池里最大线程数量
keepAliveTime当线程池线程数量大于carepoolsize,多出来的空闲线程,多长时间销毁
unit时间单位
workQueue任务队列,用于存放提交但是尚未被执行的任务
threadFactory线程工厂,用来创建线程
handler拒绝策略,是将任务添加到线程池中,线程池拒绝该任务多采取相应的措施
 
常见的工作队列
ArrayBlockingQueue基于数组有界阻塞队列
LinkedBlockingQueue基于链表有界阻塞队列
 
线程池提供了四种拒绝策略
1.AbortPolicy直接抛出异常,默认的策略
2.CallerRunPolicy用调用者所在的线程来执行任务
3.DiscardOldestPolicy丢弃阻塞队列中最靠前的任务并执行当前任务
4.DiscardPolicy直接丢弃任务
 
创建线程的四种方式
线程的同步
线程之间的通信
线程类的常用方法

 

   今天的实例也有很多,通过实例可以将所学的知识结合起来,来看看今天的实例吧!!

 1 package D0804;
 2 
 3  public class Test {
 4     private float account;
 5 
 6      public void ATM(float money){
 7         this.account=money;
 8     }
 9     public synchronized  float getAccount(){
10         try {
11             Thread.sleep(2000);
12         }catch (InterruptedException e){
13             e.printStackTrace();
14         }
15         return account;
16     }
17     public  synchronized  void deposit(float money){
18         account+=money;
19     }
20     public  synchronized void drawMoney(float money) throws Exception{
21         if(account<money){
22             throw  new Exception("余额不足!");
23         }
24         account-=money;
25     }
26 
27      }
28 class UserA extends Thread{
29     private Test atm;
30     private float money;
31     public  UserA(Test a,float m){
32         atm=a;
33         money=m;
34     }
35     public  void run(){
36         System.out.println("账户存款数额为:"+atm.getAccount()+"元!");
37         System.out.println("账户用A存了:"+money+"元!");
38         try {
39             atm.deposit(money);
40         }catch (Exception e){
41             System.out.println("余额为:"+atm.getAccount()+"元!");
42         }
43     }
44 }
45 class UserB extends Thread{
46     private Test atm;
47     private  float money;
48     public UserB(Test a,float m){
49         atm=a;
50         money=m;
51     }
52     public  void run(){
53         System.out.println("账户存款数额为:"+atm.getAccount()+"元!");
54         System.out.println("账户用B取了:"+money+"元!");
55         try {
56             atm.drawMoney(money);
57             System.out.println("余额为:"+atm.getAccount()+"元!");
58         }catch (Exception e){
59             System.out.println(e.getMessage());
60         }
61     }
62 }
63 class Test1{
64     public static void main(String[] args) {
65         Test atm=new Test();
66         UserA userA=new UserA(atm,100);
67         UserB userB=new UserB(atm,50);
68         userA.start();
69         try {
70             userA.join();
71         }catch (InterruptedException e){
72             userB.start();
73         }
74         System.out.println("==========================");
75         userB.start();
76         try {
77             userB.join();
78         }catch (InterruptedException e){
79             userA.start();
80         }
81 
82     }
83 }
 1 package D0804;
 2 
 3 import java.util.ArrayList;
 4 import java.util.concurrent.Semaphore;
 5 
 6 public class Ch04 extends Thread{
 7     private  final  static  String name="哲学家";
 8     private  final  int num;
 9     private  volatile ArrayList<Semaphore>semaphores;
10     public Ch04(int num,ArrayList<Semaphore>semaphores){
11         super(Ch04.name+String.valueOf(num));
12         this.num=num;
13         this.semaphores=semaphores;
14     }
15 
16     @Override
17     public void run() {
18         try {
19             if(this.num%2==0){
20                 semaphores.get(this.num).acquire();
21                 Thread.sleep(1000);
22                 semaphores.get(this.getRightSemaphoreIndex(this.num)).acquire();
23             }else {
24                 semaphores.get(this.getRightSemaphoreIndex(this.num)).acquire();
25                 Thread.sleep(1000);
26                 semaphores.get(this.num).acquire();
27             }
28             System.out.println(this.getName()+"获得了筷子"+String.valueOf(this.num)+"和"+String.valueOf(this.getRightSemaphoreIndex(this.num))+"开始吃饭");
29 
30         }catch (Exception e){
31             e.printStackTrace();
32         }
33         finally {
34             semaphores.get(this.num).release();
35             semaphores.get(this.getRightSemaphoreIndex(this.num)).release();
36         }
37 
38     }
39     private int getRightSemaphoreIndex(int num){
40         return (num-1<0)?semaphores.size()-1:num-1;
41     }
42 
43     public static void main(String[] args) {
44         ArrayList<Semaphore>semaphores1=new ArrayList<>();
45         int counter=5;
46         for (int i = 0; i < counter ; i++) {
47             semaphores1.add(new Semaphore(1));
48         }
49         for (int i = 0; i < counter; i++) {
50             new Ch04(i,semaphores1).start();
51         }
52     }
53 }

 

posted on 2022-08-04 20:59  于芮  阅读(24)  评论(0编辑  收藏  举报

导航