当前位置: 首页 > news >正文

任务平台网站建设国内it培训机构排名

任务平台网站建设,国内it培训机构排名,怎么样做网站管理员,wordpress主题的使用并发编程 1.共享模型-内存 共享变量在多线程间的<可见性>问题与多条指令执行时的<有序性>问题 1.1Java内存模型 JMM它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存CPU指令优化等. JMM体现在&#xff1a; 原子性-保证指令不会受到线程上…

并发编程

1.共享模型-内存

共享变量在多线程间的<可见性>问题与多条指令执行时的<有序性>问题

1.1Java内存模型

JMM它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存CPU指令优化等.

JMM体现在:

  • 原子性-保证指令不会受到线程上下文切换的影响
  • 可见性-保证指令不会受cpu缓存的影响
  • 有序性-保证指令不会受cpu指令并行优化的影响

1.2可见性

问题:通过变量控制while程序不能够停下来

@Slf4j
public class KeJianXingThreadD2 {static boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (flag) {}});thread.start();Thread.sleep(3);log.debug("停止thread");flag = false;}
}

分析问题:

  • thread从内存读取了flag的值到工作内存中
  • thread线程频繁从主内存中读取flag的值,JIT编译器会将flag的值缓存到自己的工作内存中,减少对主内存中flaga的访问,提高效率
  • 3秒之后,main线程修改了flag的值,并同步到主内存中,而thread线程一直在读取自己的工作内存的值,一直是旧值,所以线程不会停下来

解决方案:

volatile(关键字)

可以修饰成员变量和静态成员变量,可以避免线程从自己的工作缓存中查找变量,必须到主内存获取它的值,线程操作volatile变量都是直接操作主

public class KeJianXingThreadD2 {volatile static boolean flag = true;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (flag) {}});thread.start();Thread.sleep(3);log.debug("停止thread");flag = false;}
}

只能保证可见性 不能保证原子性

1.3有序性

程序执行的顺序按照代码的先后执顺序执行.

编译器和处理器为了提高执行的效率性能,会对执行进行重排序,指令重排序对单线程应用没有影响,但是在多线程环境下可能出现问题.<重排序的代码没有执行完>

解决:volatile关键字解决

1.4volatile原理

  • 读屏障
  • 写屏障

2.共享模型-无锁

  • CAS与volatile
  • 原子整数
  • 原子引用
  • 原子累加器
  • Unsafe

2.1CAS与volatile

/*** @program: springboot-demo-liuan* @description:* @author: Mr.Lh* @create: 2023-03-18 21:29**/
public class CasController {public static void main(String[] args) throws InterruptedException {Acout acout = new Acout(10000);acout.demo(acout);}
}class Acout {public AtomicInteger balance;public Acout(int count) {this.balance = new AtomicInteger(count);}public void with(Integer amout) {while (true) {int i = balance.get();int b = i - amout;if (balance.compareAndSet(i, b)) {break;}}}void demo(Acout acout) throws InterruptedException {for (int i = 0; i < 1000; i++) {new Thread(()->{acout.with(10);}).start();}Thread.sleep(1000);System.out.println(acout.balance.get());}
}

关键点是compareAndSet,它的简称是CAS,它必须是原子性的操作

CAS特点

CAS和volatile可以实现无锁并发,适用于线程数小,多核CPU的场景下

  • CAS是基于乐观锁的思想
  • synchronized是基于悲观锁的思想
  • CAS体现的是无锁并发,无阻塞并发

CAS缺点

  • ABA问题:A值变成了B,然后又从B值变回了A,而使用CAS并不会感知到这个情况
  • 自旋时间过长:单次CAS并一定能够成功,CAS配合循环来使用

原子整数

  • AtomicInteger
  • AtomicBoolean
  • AtomicLong

原子引用

  • AtomicReference(会有ABA的问题)
  • AtomicStampedReference(版本号解决ABA的问题)

3.线程池

1.线程池状态

ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量

状态名高 3 位接收新任务处理阻塞队列任务说明
RUNNING111YY
SHUTDOWN000NY不会接收新任务,但会处理阻塞队列剩余 任务
STOP001NN会中断正在执行的任务,并抛弃阻塞队列 任务
TIDYING010--任务全执行完毕,活动线程为 0 即将进入 终结
TERMINATED011--终结状态
2.构造方法
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) 
  • corePoolSize 核心线程数
  • maximumPoolSize 最大线程数
  • keepAliveTime 生存时间
  • unit 生存时间单位
  • workQueue 当核心线程数满时,存放的任务队列
  • threadFactory 创建线程的工厂
  • handler 拒绝策略
四种策略
  • CallerRunsPolicy 让调用者运行任务
  • DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之
  • AbortPolicy 让调用者抛出异常 默认策略
  • DiscardPolicy 放弃本次任务
工厂创建线程
1.newFixedThreadPool

特点:

  • 核心线程数==最大线程数,无需超时时间
  • 阻塞队列是无界的,可以任意数量的任务
2.newCachedThreadPool

特点:

  • 核心线程数是0,最大线程数无限制,60s回收救急线程,救济线程可以无限的创建
  • 队列采用的SynchronousQueue 没有容量,没有线程来取是放不进去的
  • 没有上限的一个线程池
3.newSingleThreadExecutor

特点

  • 线程数固定为1,会放入无界队列中,任务执行完毕,这唯一的线程也不会被释放
任务调度线程池
//延时执行任务
public class TimeExcetor {public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);scheduledExecutorService.schedule(() -> {System.out.println("aaaa");}, 2, TimeUnit.MILLISECONDS);scheduledExecutorService.schedule(() -> {System.out.println("bbbbbb");}, 1, TimeUnit.MILLISECONDS);}
}//定时执行任务
@Slf4j
public class TimeExcetor {public static void main(String[] args) {ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);log.debug("start...");pool.scheduleAtFixedRate(() -> {log.debug("running...");}, 1, 1, TimeUnit.SECONDS);}
}
正确处理执行任务异常
  • 主动捕获异常

    public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);scheduledExecutorService.execute(() -> {try {int i = 10 / 0;} catch (Exception ex) {ex.printStackTrace();}System.out.println("aaa");});
    }
    
  • Future

    public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(2);Future<Boolean> submit = executorService.submit(() -> {int i = 10 / 0;return true;});//如果任务执行成功则获取值,如果任务失败了 则会打印出异常信息System.out.println(submit.get());
    }
    

4.JUC

4.1 AQS原理

AbstractQueuedSynchronizer,是一个用于实现锁和同步器的基础框架

特点:

  • state state 表示同步状态(分独占锁和共享锁) 使用compareAndSetState机制实现加锁
  • Node表示队列元素,每个 Node 对象内都保存着当前线程的引用,这些 Node 构成了一个双向队列
4.2ReentrantReadWriteLock

ReentrantReadWriteLock 同样基于 AQS 实现了一套高效的同步机制。它维护着两个锁,一个读取锁和一个写入锁。读取锁允许多个线程同时共享读操作,而写入锁则只允许一个线程进行写入操作。如果有一个线程已经获取了写入锁,那么其他所有线程都无法获得读取或写入锁,它们只能等待写入锁被释放后才能进行读取或写入操作。

4.3Semaphore

是一种在并发编程中经常使用的同步原语。它可以用来管理一组共享的资源,防止共享资源的并发使用。Semaphore包含一个计数器和两个方法:acquire和release

@Slf4j
public class SemaphoreDemo1 {public static void main(String[] args) {Semaphore semaphore = new Semaphore(2);for (int i = 0; i < 10; i++) {new Thread(()->{try {semaphore.acquire();log.info("获取信号量");Thread.sleep(10002);} catch (InterruptedException e) {throw new RuntimeException(e);}finally {semaphore.release();}}).start();}}
}

4.4CountDownLatch

是一个同步工具,它可以让一个线程等待一组操作的完成。CountDownLatch包含一个计数器和两个方法:countDown和await

countDown方法将计数器的值减一,await方法阻塞线程,直到计数器值为零。每次调用countDown方法都会减少计数器的值,当计数器值为零时,await方法会解除所有等待线程的阻塞状态

@Slf4j
public class CountDownLatchDemo1 {public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(3);new Thread(()->{try {Thread.sleep(1000);countDownLatch.countDown();} catch (InterruptedException e) {throw new RuntimeException(e);}}).start();new Thread(()->{try {Thread.sleep(2222);} catch (InterruptedException e) {throw new RuntimeException(e);}countDownLatch.countDown();}).start();new Thread(()->{try {Thread.sleep(3333);} catch (InterruptedException e) {throw new RuntimeException(e);}countDownLatch.countDown();}).start();//主线程阻塞countDownLatch.await();}
}

4.5CyclicBarrier

循环栅栏,用来进行线程协作,等待线程满足某个计数。构造时设置『计数个数』,每个线程执 行到某个需要“同步”的时刻调用 await() 方法进行等待,当等待的线程数满足『计数个数』时,继续执行

public class CyclicBarrierDemo {public static void main(String[] args) {CyclicBarrier cb = new CyclicBarrier(2); // 个数为2时才会继续执行new Thread(()->{System.out.println("线程1开始.."+new Date());try {cb.await(); // 当个数不足时,等待} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}System.out.println("线程1继续向下运行..."+new Date());}).start();new Thread(()->{System.out.println("线程2开始.."+new Date());try { Thread.sleep(2000); } catch (InterruptedException e) { }try {cb.await(); // 2 秒后,线程个数够2,继续运行} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}System.out.println("线程2继续向下运行..."+new Date());}).start();}
}
http://www.ritt.cn/news/29233.html

相关文章:

  • 部委网站建设管理职责百度识图搜索网页版
  • 中山网站建设seo135谷歌chrome安卓版
  • 长沙品牌网站建设西安网站制作推广
  • 网站建设公司有多少安仁网络推广
  • 新网站建设需要什么同城发广告的平台有哪些
  • 网站建设河南人工智能培训班收费标准
  • 我做外贸要开国际网站吗网站运营策划书
  • 怎么做乞讨网站湖南长沙今日疫情
  • 哪些网站可以做网站线上电脑培训班
  • 建设网站制作武汉做搜索引擎推广的公司
  • 网站建设及运维合同北京网站制作400办理多少钱
  • 如何做一个个人网站seo搜索引擎优化工程师招聘
  • 南宁网站开发价格网盘网页版
  • 做网站一屏一屏的百度网址安全中心怎么关闭
  • 电商网站的数据库设计百度 搜索热度
  • 荷城网站设计百度推广开户联系方式
  • 荆门做网站百度推广优化中心
  • 网站主页的布局方式百度公司注册地址在哪里
  • shopex网站百度收录刷排名
  • 做seo是要先有网站吗广州关键词seo
  • 美食网站开发的难点策划网络营销方案
  • 毕业设计做健身房网站的意义廊坊seo排名
  • 网站怎么进入后台管理网络广告营销方案策划内容
  • 腾讯云主机 wordpress徐州seo
  • 网站规划的原则是什么玄幻小说百度风云榜
  • 天津品牌网站设计网站建设方案推广
  • 网站开发前准备百度推广账号出售
  • 在线网站做情侣头像公众号引流推广平台
  • 黄页88网能不能发免费的广告上海外包seo
  • 佛山网站开发青岛网站seo分析