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

学校网站建设制度网站相关推荐怎么做

学校网站建设制度,网站相关推荐怎么做,优客逸家网站源码,怎么引流客源最好的方法目录 一、线程的创建和运行 1.1 创建和运行线程的三种方法 1.2 三者之间的继承关系 二、Thread类和Runnable接口的区别 2.1 Runnable接口可以实现线程之间资源共享#xff0c;而Thread类不能 2.2 实现Runnable接口相对于继承Thread类的优点 三、实现 Runnable 接口和实现 Call… 目录 一、线程的创建和运行 1.1 创建和运行线程的三种方法 1.2 三者之间的继承关系 二、Thread类和Runnable接口的区别 2.1 Runnable接口可以实现线程之间资源共享而Thread类不能 2.2 实现Runnable接口相对于继承Thread类的优点 三、实现 Runnable 接口和实现 Callable 接口的区别 四、Thread类和Runnable接口关于启动线程的源码解析 4.1 实现方法 4.2 Thread.start()方法源码分析 4.3 Runnable.run()方法源码分析 4.4 总结 一、线程的创建和运行 1.1 创建和运行线程的三种方法 Java里的程序天生就是多线程的那么有几种启动线程的方式  Java 线程创建有3种方式 继承 Thread 类并且重写 run 方法实现 Runnable接口的 run 方法使用 Callable接口和FutureTask类方式 1.2 三者之间的继承关系 public class Thread implements Runnable {} Thread类也是实现的Runnable接口。 单独说下 FutureTask 的方式这种方式的本身也是实现了Runnable 接口的 run 方法看它的继承结构就可以知道。 前两种方式都没办法拿到任务的返回结果但是 Futuretask 方式可以。 由此我们知道了其实这三种创建方法的根源都是来源于Runnable接口这三种方法往上层追溯都能追到Runnble接口。 二、Thread类和Runnable接口的区别 2.1 Runnable接口可以实现线程之间资源共享而Thread类不能 实际上Thread类和Runnable接口之间在使用上也是有所区别的如果一个类继承Thread类就不适合于多个线程共享资源而实现了Runnable接口则可以方便的实现资源的共享。 由上文我们就可以知道Thread类和Runnable接口最大的区别就是继承Thread类不能资源共享而实现Runnable接口可以资源共享。  为什么Runnable可以共享数据 总结起来原因就是用Runnable接口的方法可以对两个不同的Thread类的构造方法传入相同的实现Runnable接口的对象那么这两个不同的Thread线程类本质操控的是同一个Runnable接口的实现对象了调用的也是同一个run()方法自然这两个线程下就实现了共享同一个Runnable实现类中的数据了。 如果两个Thread类的构造方法传入不同的Runnable接口实现类那么两个Thread线程对象操作的不是同一个Runnable实现类两个线程也就不能共享数据了。 2.2 实现Runnable接口相对于继承Thread类的优点 可见实现Runnable接口相对于继承Thread类来说有如下显著的优势 适合多个相同程序代码的线程去处理同一资源的情况。可以避免由于Java的单继承特性带来的局限。增强了程序的健壮性代码能够被多个线程共享代码与数据是独立的。线程池只能放入实现 Runable 或 Callable 类线程不能直接放入继承 Thread 的类 三、实现 Runnable 接口和实现 Callable 接口的区别 Runnable 是自从 java1.1 就有了而 Callable 是 1.5 之后才加上去的实现 Callable 接口的任务线程能返回执行结果而实现 Runnable 接口的任务线程不能返回结果Callable 接口的 call()方法允许抛出异常而 Runnable 接口的 run()方法的异常只能在内部消化不能继续上抛加入线程池运行Runnable 使用 ExecutorService 的 execute 方法Callable 使用 submit 方法。注Callable 接口支持返回执行结果此时需要调用 FutureTask.get()方法实现此方法会阻塞主线程直到获取返回结果当不调用此方法时主线程不会阻塞 四、Thread类和Runnable接口关于启动线程的源码解析 这里我们来讲一下Java中创建线程最经典的这两种方式在底层源码是如何实现的。 4.1 实现方法 Java 中实现多线程有两种「基本方式」继承 Thread 类和实现 Runnable 接口。从实现的编程手法来看认为这是两种实现方式并无不妥。但是究其实现根源这么讲其实并不准确。 其实多线程从根本上讲只有一种实现方式就是实例化 Thread并且提供其执行的 run 方法。无论你是通过继承 Thread还是实现 Runnable接口最终都是重写或者实现了 run 方法。而你真正启动线程都是通过实例化 Thread调用其 start 方法。 来看下两种不同实现方式的例子 1. 继承 Thread 方式 public class MyThread extends Thread { public void run() { System.out.println(MyThread.run()); } } MyThread myThread1 new MyThread(); MyThread myThread2 new MyThread(); myThread1.start(); myThread2.start(); 2. 实现 Runnable 方式 public class MyThread extends OtherClass implements Runnable { public void run() { System.out.println(MyThread.run()); } } MyThread myThread new MyThread(); Thread thread new Thread(myThread); thread.start(); 第一种方式中MyThread 继承了 Thread 类启动时调用的 start 方法其实还是他父类 Thread 的 start 方法。并最终触发执行 Student 重写的 run 方法。 第二种方式中MyThread 实现 Runnable 接口将MyThread对象作为参数传递给 Thread 构造函数。接下来还是调用了 Thread 的 start 方法。最后则会触发传入的 Runnable 实现类的 run 方法。 两种方式都是创建 Thread 或者 Thread 的子类通过 Thread 的 start 方法启动。唯一不同是第一种 run 方法实现在 Thread 子类中。第二种则是把 run 方法逻辑转移到 Runnable 的实现类中。线程启动后第一种方式是 thread 对象运行自己的 run 方法逻辑第二种方式则是调用 Runnable 实现的 run 方法逻辑。 相比较来说第二种方式是更好的实践原因如下 java 语言中只能单继承通过实现接口的方式可以让实现类去继承其它类。而直接继承 thread 就不能再继承其它类了线程控制逻辑在 Thread 类中业务运行逻辑在 Runnable 实现类中。解耦更为彻底实现 Runnable 的实例可以被多个线程共享并执行。而实现 thread 是做不到这一点的。 看到这里你是不是很好奇为什么程序中调用的是 Thread 的 start 方法而不是 run 方法为什么线程在调用 start 方法后会执行 run 方法的逻辑呢接下来我们通过学习 start 方法的源代码来找到答案。 4.2 Thread.start()方法源码分析 Thread类的无参构造方法 public Thread() {init(null, null, Thread- nextThreadNum(), 0); } 如果是直接创建Thread类对象我们通过源码就能看出传入到target是空。在这种情况下我们需要在Thread的继承类中去覆写run()方法这样在Thread类执行run()方法的时候就是调用我们继承类中覆写的run()方法逻辑。 我们知道Thraed类的对象是不能直接调用run()方法的那么它是如何调用run()方法的呢下面我们接着来进行分析。 Thread类中start()方法源码 public synchronized void start() {if (threadStatus ! 0)throw new IllegalThreadStateException(); group.add(this);boolean started false;try { start0(); started true; } finally {try {if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } }这段代码足够简单简单到没什么内容。主要逻辑如下 检查线程的状态是否可以启动把线程加入到线程 group 中调用了 start0 () 方法。 可以看到 Start 方法中最终调用的是 start0()方法并不是 run 方法。那么我们再看 start0 方法源代码 private native void start0(); 什么也没有因为 start0 是一个 native 方法也称为 JNI(Java Native Interface)方法。JNI 方法是 Java和其它语言交互的方式。同样也是 Java代码和虚拟机交互的方式虚拟机就是由 C 和汇编所编写。 由于 start0 是一个 native 方法所以后面的执行会进入到 JVM 中。那么 run 方法到底是何时被调用的呢这里似乎找不到答案了。 难道我们错过了什么回过头来我们再看看 Start 方法的注解。其实读源代码的时候要先读注解否则直接进入代码逻辑容易陷进去出不来。原来答案就在 start 方法的注解里我们可以看到 /* * Causes this thread to begin execution; the Java Virtual Machine* calls the run method of this thread.* * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * start method) and the other thread (which executes its * run method). * * * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed execution. */最关键一句: the Java Virtual Machine calls the run method of this thread。由此我们可以推断出整个执行流程如下 start 方法调用了 start0 方法start0 方法在 JVM 中start0 中的逻辑会调用 run 方法。 至此我们已经分析清楚从线程创建到 run 方法被执行的逻辑。但是通过实现 Runnbale 的方式实现多线程时Runnable 的 run 方法是如何被调用的呢 4.3 Runnable.run()方法源码分析 我们先从 Thread 的构造函数入手。原因是 Runnable 的实现对象通过构造函数传入 Thread。 Thread类构造方法源码 public Thread(Runnable target) { init(null, target, Thread- nextThreadNum(), 0); } 可以看到 Runnable 实现作为 target 对象传递进来。再次调用了 init 方法init 方法有多个重载最终调用的是Thread类中的如下方法 private void init(ThreadGroup g, Runnable target, String name, long stackSize) {Thread parent currentThread();if (g null) {g parent.getThreadGroup();}g.addUnstarted();this.group g;this.target target;this.priority parent.getPriority();this.daemon parent.isDaemon();setName(name);init2(parent);/* Stash the specified stack size in case the VM cares */this.stackSize stackSize;tid nextThreadID(); }此方法里有一行代码 this.target target; 原来 target 是 Thread类的成员变量 /* What will be run. */ private Runnable target; 此时Thread 的 target 被设置为你实现业务逻辑的 Runnable 实现。 我们再看下Thread类的run 方法的代码 Override public void run() {if (target ! null) { target.run(); } } 看到这里是不是已经很清楚了当你传入了 target时target不为null在执行Thread类的run()方法时其实会调用执行 target 的 run 方法。也就是执行你实现业务逻辑的方法我们需要在实现Runnable接口的类中实现Runnable接口的run()方法。整体执行流程如下 如果你是通过继承 Thread重写 run 方法的方式实现多线程。那么在上图中的第三步执行的就是你重写的 run 方法。 我们回过头看看 Thread 类的定义 public class Thread implements Runnable 原来 Thread 也实现了 Runnable 接口。怪不得 Thread 类的 run 方法上有 Override 注解。所以继承 Thread类实现多线程其实也相当于是实现 Runnable 接口的 run 方法。只不过此时不需要再传入一个 Thread 类去启动。它自己已具备了 Thread 的功能自己就可以运转起来。既然 Thread 类也实现了 Runnable 接口那么 Thread 子类对象是不是也可以传入另外的 Thread 对象让其执行自己的 run 方法呢答案是可行的。 4.4 总结 以上对多线程的两种实现方式做了分析。在学习多线程的同时我们也应该学习源代码中优秀的设计模式。Java 中多线程的实现采用了模板模式。Thread 是模板对象负责线程相关的逻辑比如线程的创建、运行以及各种操作。而线程真正的业务逻辑则被剥离出来交由 Runnable 的实现类去实现。线程操作和业务逻辑完全解耦普通开发者只需要聚焦在业务逻辑实现。 执行业务逻辑是 Thread 对象的生命周期中的重要一环。这一步通过调用传入 Runnable 的 run 方法实现。Thread 线程整体逻辑就是一个模板把其中一个步骤剥离出来由其他类实现这就是模板模式。 相关文章【并发基础】线程进程协程的详细解释                   【操作系统】一篇文章带你快速搞懂用户态和内核态
http://www.w-s-a.com/news/449624/

相关文章:

  • 昌图网站wordpress 视频外链
  • 企业网站要怎么建设重庆住房城乡建设部网站
  • html5网站特点seo教程培训班
  • 深圳网站建设哪个最好网站 多语
  • 互联网工具型网站创意网络广告
  • 影视公司网站建设网页界面设计分辨率是多少dpi
  • 免费的做微博的网站模板wordpress 页面 首页
  • 摄影图片网站网站辅导运营与托管公司
  • 做课件的网站长春免费建站模板
  • 响应式网站模板下载免费wordpress 小工具移动
  • 网站标签title在线app制作平台
  • 做电器推广的网站简洁大方的网站模板
  • 网站开发的平台100个详情页设计图
  • wordpress淘宝客建站教程视频知名的设计公司网站
  • 批量做单页网站怎么直接用代码做网站
  • 百度收录较好的网站办公室装修设计方案
  • 建设购物网站要求cnzz数据统计
  • 深圳自适应网站建设价格广东网站建设软件
  • 网页设计介绍北京网站自己做彩票网站
  • 最牛论坛网站app生成链接
  • 用jsp做的网站源代码网站优化说明
  • 网站建设公司名字甘肃省和住房建设厅网站
  • 做外贸网站需要什么卡网站建设公司怎样
  • 网站关键词密度怎么计算的中文版wordpress
  • asp网站建设教程如何在线上推广自己的产品
  • 电脑网站你懂我意思正能量济南网站建设公司熊掌号
  • 杂志社网站建设萧山区网站建设
  • 电商网站前端制作分工网站怎做百度代码统计
  • 免费的html大作业网站网站开发心得500字
  • 临时工找工作网站做美缝帮别人做非法网站