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

wordpress承载压力/seo入门免费教程

wordpress承载压力,seo入门免费教程,网站建设 鸿,360浏览器打不开90设计网站文章目录一:volatile二:synchronized 临界区方式ReentrantLock/Condition 消息队列方式三:使用JUC工具类 CountDownLatch四:基本LockSupport实现线程间的阻塞和唤醒五:通过Socket网络通信六:信号量机制(Sem…

文章目录

  • 一:volatile
  • 二:synchronized 临界区方式
  • ReentrantLock/Condition 消息队列方式
  • 三:使用JUC工具类 CountDownLatch
  • 四:基本LockSupport实现线程间的阻塞和唤醒
  • 五:通过Socket网络通信
  • 六:信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
  • 七:管道通信就是使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信

这篇博客是是我在学习了多线程并发和操作系统后,针对Java中的情况,为保证线程安全和线程的并发运行进行总结的博客。
看了我的博客后如果哪里我有理解不到位地方欢迎大家评论区给我留言,感谢支持。

  • 引言
    Java支持多个线程同时访问一个对象或者对象的成员变量,由于每个线程可以拥有这个变量的拷贝(虽然对象以及成员变量分配的内存是在共享内存(堆)中的,但是每个执行的线程还是可以拥有一份拷贝,这样做的目的是加速程序的执行,这是现代多核处理器的一个显著特性),所以程序在执行过程中,一个线程看到的变量并不一定是最新的。所以在多个线程访问同一个数据时会将变量拷贝到自己线程独有的栈中进行数据的操作,在操作完后在把数据放回共享内存。这时就会有多线程并发的安全问题出现。保证多线程的并发运行,我们就需要多线程相互进行配合,那么这时就引出了线程间的通信。这里线程和进程概念不相同,因为Java的程序是运行于JVM之上,所以进程概念大家可以自行去了解。这篇博客主要讲Java里多线程之间的通信。

  • 首先,要短信线程间通信的模型有两种:共享内存和消息传递,以下方式都是基本这两种模型来实现的。

  • 题目:
    有两个线程A、B,A线程向一个集合里面依次添加元素"abc"字符串,一共添加十次,当添加到第五次的时候,希望B线程能够收到A线程的通知,然后B线程执行相关的业务操作。

一:volatile

关键字volatile可以用来修饰字段(成员变量),就是告知程序任何对该变量的访问均需要从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性。

使用while进行轮询在这种方式下,线程A不断地改变条件,线程ThreadB不停地通过while语句检测这个条件(list.size==5)是否成立 ,从而实现了线程间的通信。但是这种方式会浪费CPU资源。之所以说它浪费资源,是因为JVM调度器将CPU交给线程B执行时,它没做啥“有用”的工作,只是在不断地测试某个条件是否成立。

public class TestSync {// 定义一个共享变量来实现通信,它需要是volatile修饰,否则线程不能及时感知static volatile boolean notice = false;public static void main(String[] args) {List<String>  list = new ArrayList<>();// 实现线程AThread threadA = new Thread(() -> {for (int i = 1; i <= 10; i++) {list.add("abc");System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (list.size() == 5)notice = true;}});// 实现线程BThread threadB = new Thread(() -> {while (true) {if (notice) {System.out.println("线程B收到通知,开始执行自己的业务...");break;}}});// 需要先启动线程BthreadB.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 再启动线程AthreadA.start();}
}

在这里插入图片描述

二:synchronized 临界区方式

synchronized和ReentrantLock实现原理上有所不同,但是针对线程之间的通信的思想相同,都是保证多个线程互斥访问临界区(共享存储),来实现线程间的通信。

  • synchronized
    根据synchronized原理使用Object类提供了线程间通信的方法:wait()、notify()、notifyaAl()方法来实现多个线程互斥访问临界区资源,Object类这几个方法必须配合synchronized来进行使用。
public class TestSync {public static void main(String[] args) {// 定义一个锁对象Object lock = new Object();List<String>  list = new ArrayList<>();// 实现线程AThread threadA = new Thread(() -> {synchronized (lock) {for (int i = 1; i <= 10; i++) {list.add("abc");System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (list.size() == 5)lock.notify();// 唤醒B线程}}});// 实现线程BThread threadB = new Thread(() -> {while (true) {synchronized (lock) {if (list.size() != 5) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程B收到通知,开始执行自己的业务...");}}});// 需要先启动线程BthreadB.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 再启动线程AthreadA.start();}
}

在这里插入图片描述

ReentrantLock/Condition 消息队列方式

  • ReentrantLock/Condition
    ReentrantLock锁的实现原理虽然和synchronized不用,但是它和synchronized一样都是通过保证线程间的互斥访问临界区,来保证线程安全,实现线程间的通信。相比于synchronized使用Object类的三个方法来实现线程的阻塞和运行两个状态的切换,ReentrantLock使用Condition阻塞队列的await()、signal()、signalAll()三个方法来实现线程阻塞和运行两个状态的切换,进而实现线程间的通信。
public class TestSync {public static void main(String[] args) {ReentrantLock lock = new ReentrantLock();Condition condition = lock.newCondition();List<String> list = new ArrayList<>();// 实现线程AThread threadA = new Thread(() -> {lock.lock();for (int i = 1; i <= 10; i++) {list.add("abc");System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (list.size() == 5)condition.signal();}lock.unlock();});// 实现线程BThread threadB = new Thread(() -> {lock.lock();if (list.size() != 5) {try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程B收到通知,开始执行自己的业务...");lock.unlock();});threadB.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}threadA.start();}
}

在这里插入图片描述
显然这种方式使用起来并不是很好,代码编写复杂,而且线程B在被A唤醒之后由于没有获取锁还是不能立即执行,也就是说,A在唤醒操作之后,并不释放锁。这种方法跟 Object 的 wait() 和 notify() 一样。

三:使用JUC工具类 CountDownLatch

jdk1.5之后在java.util.concurrent包下提供了很多并发编程相关的工具类,简化了我们的并发编程代码的书写,***CountDownLatch***基于AQS框架,相当于也是维护了一个线程间共享变量state

public class TestSync {public static void main(String[] args) {CountDownLatch countDownLatch = new CountDownLatch(1);List<String>  list = new ArrayList<>();// 实现线程AThread threadA = new Thread(() -> {for (int i = 1; i <= 10; i++) {list.add("abc");System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (list.size() == 5)countDownLatch.countDown();}});// 实现线程BThread threadB = new Thread(() -> {while (true) {if (list.size() != 5) {try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程B收到通知,开始执行自己的业务...");break;}});// 需要先启动线程BthreadB.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 再启动线程AthreadA.start();}
}

在这里插入图片描述

四:基本LockSupport实现线程间的阻塞和唤醒

LockSupport 是一种非常灵活的实现线程间阻塞和唤醒的工具,使用它不用关注是等待线程先进行还是唤醒线程先运行,但是得知道线程的名字。

public class TestSync {public static void main(String[] args) {List<String> list = new ArrayList<>();// 实现线程Bfinal Thread threadB = new Thread(() -> {if (list.size() != 5) {LockSupport.park();}System.out.println("线程B收到通知,开始执行自己的业务...");});// 实现线程AThread threadA = new Thread(() -> {for (int i = 1; i <= 10; i++) {list.add("abc");System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (list.size() == 5)LockSupport.unpark(threadB);}});threadA.start();threadB.start();}
}

在这里插入图片描述

五:通过Socket网络通信

网络通信例如我们的NIO,BIO通过Socket套接字来进行通信
这里代码在我的另外一篇博客中写到NIO/BIO的Java实现
当然还有我们的各种网络通信框架例如netty等等。都是通过网络通信来实现多线程的通信。

网络通信和前面的不同,他是基于Socket实现的,所以不是牵扯前面所说的共享内存之类的概念,当然因为是网络通信,它可以实现不同设备间的通信。

六:信号量机制(Semaphore):包括无名线程信号量和命名线程信号量

这个大家可以自行进行查询

七:管道通信就是使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信

管道通信这里不做具体阐述,感兴趣朋友可自行了解。

http://www.lbrq.cn/news/1372213.html

相关文章:

  • 上海住房和建设交通委员会网站/万网商标查询
  • php网站建设与维护/百度一下首页网页
  • 网站建设背景和目标/品牌推广方式都有哪些
  • 浙江省政府加强政府网站建设方案/百度网络营销中心app
  • 重庆做网站的公司有哪些/网站主题
  • 贵金属网站模板/怎样推广自己的网站
  • 做天猫网站要多少钱/代发新闻稿最大平台
  • 做网站推广的优势/网站收录一般多久
  • 网站被攻击怎么让百度重新蜘蛛自动抓/网络营销的推广手段
  • asp.net 动态网站开发/淘宝关键词指数查询
  • 怎么做网站给国外看见/怎么网上推广自己的产品
  • 代理公司注册有哪些/seo难不难
  • 备案网站名怎么写/电商运营培训正规平台
  • 石家庄网站建设seo/软文发布的平台与板块
  • 餐饮类网站设计/西安发布最新通知
  • 地推加人2元1个/seo的培训班
  • 做夏促的网站有哪些/杭州龙席网络seo
  • 买个网站域名要多少钱一年/百度做网站
  • 做网约车网站/今天的新闻内容
  • 科技公司 网站模板/今日头条网页版
  • easy ssl wordpress/seo检测
  • 公司注册地址怎么变更/山西搜索引擎优化
  • 公司网站怎么做分录/百度直播平台
  • 制作一个有用户网站/关键词挖掘爱站网
  • b s架构做的网站/营销型企业网站制作
  • 网站建设职业描述/网站seo应用
  • 网站建设配置文件无法粘贴/百度指数的网址
  • 公司简介制作/安卓神级系统优化工具
  • 手机网站建设哪/优化大师怎么提交作业
  • 大兴安岭做网站/百度seo推广是什么
  • 使用 BERT 的 NSP 实现语义感知切片 —— 提升 RAG 系统的检索质量
  • 路面障碍物识别漏检率↓76%:陌讯多模态融合算法实战解析
  • 蓝桥杯----串口
  • 深入 Go 底层原理(三):Goroutine 的调度策略
  • 简化理解I2C总线
  • ART数据库索引结构--ART,The adaptive radix tree论文细读