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

青岛北京网站建设网站推广目的

青岛北京网站建设,网站推广目的,人力资源公司经营范围,做网站练手java多线程基础 下面说一下线程的7种状态 下面我重点来说一下阻塞状态 阻塞状态是可以分很多种的#xff1a; 下面用另外一张图来说明这种状态 简单说一下线程的启动原理 下面说一下java中的线程 java线程的异步请求方式 上面就会先把main执行出来#xff0c;等阻塞结束之后… java多线程基础  下面说一下线程的7种状态 下面我重点来说一下阻塞状态 阻塞状态是可以分很多种的 下面用另外一张图来说明这种状态 简单说一下线程的启动原理 下面说一下java中的线程 java线程的异步请求方式 上面就会先把main执行出来等阻塞结束之后把run()方法里面的come in执行出来这个是一个异步的操作 从线程中取得一个返回值 1.用一个类去实现Callable接口 上面可以返回一个结果 import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;// 实现Callable接口指定返回值类型为String public class CallableDemo implements CallableString {// 实现call方法该方法内为具体的任务逻辑Overridepublic String call() throws Exception {System.out.println(come in); // 输出提示信息Thread.sleep(10000); // 休眠10秒模拟耗时操作return SUCCESS; // 返回任务执行结果}// 主函数public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建一个固定大小为1的线程池ExecutorService executorService Executors.newFixedThreadPool(1);// 创建CallableDemo实例CallableDemo callableDemo new CallableDemo();// 提交任务给线程池获得一个Future对象FutureString future executorService.submit(callableDemo);System.out.println(future.get()); // 阻塞等待任务执行完毕并获取结果executorService.shutdown(); // 关闭线程池} }我们把上面的线程交给线程池去执行然后返回一个Future对象接收返回值里面说一下future.get()方法是一个阻塞方法比如上面线程阻塞了10秒钟我们get()这个方法是拿不到结果的 interrupt()的作用 上面的运行情况下面分析一下 在某些情况下在线程中断之前可能不会打印消息“Test:1”。这是因为线程调度程序决定何时在线程之间切换并且新线程可能在有机会打印消息之前就被中断了。start方法和interrupt方法之间的执行顺序没有保证因此中断可能在线程有机会开始执行其run方法之前发生。 下面我们来看另外一段代码 package com.pxx.interrupt;public class InterruptDemo2 implements Runnable {Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {try {Thread.sleep(200);//这里睡了0.2秒System.out.println(interrupt线程运行了);} catch (InterruptedException e) {//这里会有复位的作用又把isInterrupted变为falseSystem.out.println(异常被捕获);e.printStackTrace();}}}public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(new InterruptDemo2());t1.start();Thread.sleep(1000);t1.interrupt();//把isInterrupted()这个方法变为trueSystem.out.println(Thread.currentThread().getName() 执行了);}}我们来看其中的一个运行结果 那么我们来分析一下运行结果 我先来说一下InterruptedException这个异常会在什么时候去触发它的触发条件是 !Thread.currentThread().isInterrupted()这个位置变为true的时候它就会去触发这个异常 并且又把这个异常复位为false 上面就是main主线程调用了start之后就被t1线程抢走了并开始执行然后中间main线程抢回了执行的时间片把isInterrupted变为了true这个时候t1线程又抢走了时间片发现iisInterrupted()这个方法变为了true,于是触发了异常并且复位了isInterrupted()变为了false然后开始执行catch里面的代码执行完一句之后又被main线程抢走了这个时候main执行完最后一条语句结束然后t1去执行打印异常栈追踪信息又开始一直循环执行里面的代码因为没有在让isInterrupted继续中断的条件 好了我们可以改动一下上面的代码让它继续中断 说一下并发与并行  并发是并行的假象看似程序在同时执行多个操作而并发只是要求程序假装同时执行多个操作也就是每个时间片执行一个操作多个操作快速切换执行而已 大体说一下并发编程的三大特性  可见性  当一个线程修改了共享变量的值其他线程能够看到修改的值。 具体原理分析如下 当我们在Java程序中定义了一个变量例如 int x 5;这个变量实际上在计算机内存中有两个位置保存着它的值一个是主内存主存RAM另一个是线程的工作内存缓存CPU缓存。在不同的线程中可能会有各自的工作内存。 当一个线程修改了这个变量的值例如 x 10;这个修改首先会发生在线程的工作内存中而不是直接在主内存中。其他线程如果要读取这个变量的值通常会从主内存中读取。问题在于由于工作内存的存在不同的线程可能在各自的工作内存中保存了不同的变量值。 为了确保多个线程之间对共享变量的修改能够正确地被其他线程看到Java 内存模型使用了“主内存同步”的机制。当一个线程修改了变量的值后会将新值同步回主内存而其他线程在读取这个变量的值之前会先从主内存中刷新获取变量的最新值而不是直接从自己的工作内存中读取。 下面说的直白一点就是 有序性 简单说一下什么叫指令重排 指令重排是指在程序执行过程中CPU或者编译器为了提高性能可能会对指令的执行顺序进行优化使得程序在逻辑上的执行顺序与实际的指令执行顺序不一致。 在Java中由于Java代码最终会被编译成字节码然后由JVM执行JVM为了提高程序执行的效率也可能会进行指令重排。这就意味着即使程序的源代码中顺序是有序的JVM在执行时可能会重新排列指令的执行顺序。 指令重排可能会导致多线程程序出现问题。例如如果一个线程在初始化一个对象时先为对象分配内存空间然后初始化对象的属性最后将对象的引用赋值给某个变量。如果发生了指令重排可能会导致另一个线程在获取到对象的引用之后访问到的对象并未完成初始化从而引发错误。 原子性 一个或多个操作要么全部执行且在执行过程中不被任何因素打断要么全部不执行 来说一下JMM内存模型 Java内存模型Java Memory ModelJMM 首先要明白JMM内存模型他不是一个具体硬件存在它是一个虚拟的概念。 了解了上面这个概念之后我们必须去了解一下计算机内部的重要组成部分以及jvm到底占据计算机什么位置和内存是如何划分的 直接用一张图来说明一下 好了在回过头来说JMM它是一个概念一个数据的处理规则对吧下面我们就来剖析一下这个规则 JMM规范了Java虚拟机与计算机内存是如何协同工作的 规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值以及在必须时如何同步的访问共享变量。它是围绕原子性有序性可见性展开的 单纯这样来看我们能看懂个屁啊既然是围绕可见性展开的那我们就贴一段会有可见性问题的代码来说一下 package com.pxx.visibility;public class VisibilityTest {private boolean flag true;public void refresh() {flag false;System.out.println(Thread.currentThread().getName() 修改flag);}public void load() {System.out.println(Thread.currentThread().getName() 开始执行...);int i 0;//进行循环flag truewhile (flag) {i;}System.out.println(Thread.currentThread().getName() 跳出循环 i i);}public static void main(String[] args) throws InterruptedException {VisibilityTest test new VisibilityTest();//线程threadA模拟数据加载场景Thread threadA new Thread(() - test.load(), threadA);threadA.start();//让threadA执行Thread.sleep(1000);Thread threadB new Thread(() - test.refresh(), threadB);threadB.start();}}运行结果 分析可见性 下面在用一个图来讲解一下JMM概念 上面还提到了主内存与工作内存的具体的交互操作 下面我来说一个问题我刚刚提到只要本地内存共享变量一直存在那么程序就会从本地缓存里面取数据那么什么时候本地内存会不存在呢 第一栈空间是有限的到了一定的限度之后会把变量给清理掉 第二隔了一段时间本地变量一直没有被使用也会清理掉 上面两种线程在运行的时候发现本地没有共享变量了之后都会去主内存从新加载变量到本地内存。 下面可以看一个代码实例 这个方法是让线程能隔一段纳秒的时间在运行纳秒的原因是我们可以把时间控制的非常短 上面就可能会让flag失效从而去主内存里面获取最新的数据然后跳出循环 下面讲一个Thread.yield(),他会释放当前线程的时间片让当前线程进入一个可运行状态并且保存数据下次这个线程在次执行的时候如果发现主内存已经修改了某个共享变量就会从主内存去获取这个共享变量的值 为什么volatile也可以跳出循环 我们去看一下jvm中的字节码解释器源码bytecodeInterpreter.cpp 然后内部去调用了一个内存屏障处理 x86处理器中利用lock实现类似内存屏障的效果。 lock前缀指令的作用 会等待它之前所有指令完成并且所有缓冲的写操作写回内存也就是将store buffer中的内容写入内存之后才开始执行 lock会立即把本地内存修改的变量刷新到主内存里面同时会让其他处理器中的本地内存的缓存副本失效它失效然后又会从主内存读取共享变量 他不是一个内存屏障的指令但是它有内存屏障的效果 volatile的本质 下面这个方法 UnsafeFactory.getUnsafe().storeFence(); 核心也是 //能够跳出循环    内存屏障  //System.out.println(count); //LockSupport.unpark(Thread.currentThread()); 上面都是调用内存屏障 还有就是Thread.sleep(1)这种操作也是调用了内存屏障 定义为final也会保证某个变量的可见性
http://www.dnsts.com.cn/news/147082.html

相关文章:

  • 龙象建设集团有限公司网站百度视频广告怎么投放
  • 网站建设需求说明书如何申请企业微信
  • 微信网站定制ip地址能安装wordpress
  • 品牌网站建设最佳大蝌蚪百度搜索引擎录入网站
  • 网站建设佰首选金手指十四phpcms校园网站
  • 怎样不让网站自动跳转wap南京百度seo代理
  • 做app好还是响应式网站广东建设厅官网查询平台
  • 做外汇看什么网站wordpress数据库教程
  • 设计电子商务网站为什么不建议学电子商务?
  • 建站用什么搭建比较好软件开发外包什么意思
  • 北京网站开发网站建设咨询wordpress一直加载插件
  • 绥化市建设局官方网站四川建设局网站
  • 做一个官方网站多少钱wordpress创建自定义页面模板
  • wamp网站开发视频教程阿里巴巴吧做网站
  • 网站开发为什么需要团队完成克隆网站后台
  • 威海做网站whhl做网站用到的技术
  • 网站开发项目报价单建设网站的合约
  • 网站头部ps购物网站的建设时间
  • 网站做3儿童车开场动画青海住房与城乡建设厅网站
  • 鲜花店网站建设的规模设想seo培训优化课程
  • 企业网站建设要多虚拟电脑主机平台
  • 微网站首页佛山做企业网站
  • 腾讯云网站备案流程wordpress添加支付
  • 深圳网站设计优刻技术外包网站
  • 建设部门户网站条例免费下载公司开发个网站有哪些
  • 紫金网站制作哪个网站教做西餐
  • 做h5场景的网站官方传奇游戏
  • 自己用模板做网站陕西省门户网站建设政策
  • 唐山哪个公司做网站网站建设费用用
  • 设计云网站wordpress购买按钮插件