2019独角兽企业重金招聘Python工程师标准>>>

一、进程和线程

在java语言中最大的特点就是支持多线程的开发(也是为数不多支持多线程开发的语言),如果对多线程没有一个全面而且细致的了解,在以后一定存在严重的技术缺陷。

进程:传统的dos是单进程处理,允许一个程序执行,后来到了Windows时代,出现了多线程的设计。表示在一个时间段上可以运行多个程序,并且这些程序将进行资源的轮流抢占。在同一时间点上,只有一个程序执行,后来有了多核CPU的实现。可以实现在同一时间点,多个程序同时执行。

线程:是进程的基础之上划分的更小的程序单元,线程依赖于进程的实现,线程的启动要比进程快的多。

二、Thread实现多线程

范例:  多线程主体类

class MyThread extends  Thread{private String title;public MyThread(String title){this.title = title;}@Overridepublic void run() {for (int i = 0; i< 10; i++) {System.out.println(this.title+"运行,i="+i);}}
}

多线程要执行的功能都应该在run()方法中进行定义,run()方法不能被直接调用(如果我们直接调用子线程的run()方法,其方法还是运行在主线程中,代码在程序中是顺序执行的,所以不会有解决耗时操作的问题。所以不能直接调用线程的run()方法,只有子线程开始了,才会有异步的效果。当thread.start()方法执行了以后,子线程才会执行run()方法,这样的效果和在主线程中直接调用run()方法的效果是截然不同的)。所以如果要开启多线程,必须执行start()方法。

public static void main(String[] args) {new MyThread("线程A").start();new MyThread("线程B").start();new MyThread("线程C").start();
}

执行结果:线程A,B,C交替执行,执行顺序不可控。

结论:虽然调用是start()方法,但是最终执行的是run()方法。

疑问:为什么不直接使用run()方法,而使用start()?

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) {}}
}
private native void start0();

分析start()方法源代码:抛出“IllegalThreadStateException”异常,没有throws也没有try..catch,表明此异常一定是RuntimeException的子类。一个线程只允许启动一次,否则就会抛出此异常。

列如:

public static void main(String[] args) {Thread t = new MyThread("线程A");t.start();t.start();
}

native含义:

在java执行过程中考虑到对于不同层次的开发者的需求,所以java支持有本地的操作系统函数调用,而这项技术成为JNI技术,但是Java开发过程中并不推荐这样使用,这项技术可以使用一些底层函数进行一些特殊的处理,而在start()方法里面的start0()表示需要将此方法依赖于不同的操作系统实现。

三、Runnable接口实现多线程

范例:Runnable实现

class MyThread implements  Runnable{private String title;public MyThread(String title){this.title = title;}@Overridepublic void run() {for (int i = 0; i< 10; i++) {System.out.println(this.title+"运行,i="+i);}}
}

此方式避免了单继承的局限,也能更好的进行功能扩展。以后的开发中,优先考虑Runnable来实现,但是启动多线程永远都是通过Thread对象来启动多线程。

lambda表达式写法:

public static void main(String[] args) {for (int i =0; i <3 ; i++){String title="线程对象_"+i;Runnable run=()->{for (int j = 0; j< 10; j++){System.out.println(title+"运行,j="+j);}};new Thread(run).start();}}

更简洁:

public static void main(String[] args) {for (int i =0; i <3 ; i++){String title="线程对象_"+i;new Thread(()->{for (int j = 0; j< 10; j++){System.out.println(title+"运行,j="+j);}}).start();}}

四、Thread和Runnable的关系

Thread也是Runnable接口的子类

关系图:

多线程的设计过程中,使用了代理模式,用户自定义的MyThread的类只负责项目核心功能的实现吗,而所有的辅助实现全部由Thread类来处理。

调用start()方法时候,通过Thread的构造函数传递了一个Runnable的接口对象,此对象将会被target保存,最终调用的将是Runnable子类覆盖了Runnable接口的run()方法。

多线程开发示意图:

范例:通过卖票程序来实现多个线程的资源并发访问

class MyThread implements  Runnable{private int  ticket = 5;@Overridepublic void run() {for (int i = 0; i< 100; i++) {if(this.ticket> 0) {System.out.println("卖票,ticket=" + ticket--);}}}
}public class Main {public static void main(String[] args) {MyThread mt = new MyThread();new Thread(mt).start();new Thread(mt).start();new Thread(mt).start();}
}

执行结果:

内存分析:

五、Callable实现多线程

如果要实现多线程,肯定依靠的是Runnable,但是Runnable中的run()没有返回值。所以JDK1.5后出现java.util.concurrent.Callable来实现多线程。

接口的定义:

@FunctionalInterface
public interface Callable<V> {V call() throws Exception;
}

从定义可以发现Callable定义了一个泛型,此泛型的类型就是返回数据的类型,这样的好处是避免向下转型的安全隐患。

Callable的相关关系图:

实例:Callable的线程实现

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;class MyThread implements Callable<String>{@Overridepublic String call() throws Exception {for(int i = 0; i< 10 ; i++){System.out.println("线程执行,i="+i);}return "程序执行完毕";}
}public class Main {public static void main(String[] args) {try {FutureTask<String> task = new FutureTask<>(new MyThread());new Thread(task).start();System.out.println("【线程返回数据】"+task.get());}catch(Exception e){e.printStackTrace();}}
}

执行结果:

注:Runnable和Callable的区别?

1.Runnable是在JDK1.0的时候提出的多线程的实现接口,而Callable是在JDK1.5以后提出的。

2.java.util.Runnable接口只有一个run()方法,没有返回值,java.util.concurrent.Callable接口里面只有一个call()方法,可以有返回值。

六、线程的运行状态

对于多线程的开发而言,总是先定义线程主题类,通过Thread进行线程的启动,当你调用start()方法并不意味着线程已经启动。

线程的运行状态:

1.任何一个线程对象都应该使用Thread来进行封,并且通过start()进行启动,启动的时候,线程就会进入一种就绪状态,并没有执行。

2.进入到就绪状态后,就需要等待资源调度,当某一个线程调度成功后进入运行状态(run()),但是所有的线程不可能一直持续的执行下去,中间需要产生一些暂停的状态。例如:某个线程执行一段时间后让出资源,而后,这个线程就将进入阻塞状态。随后重新回到就绪状态。

3.当run()方法执行完毕后,线程的主要任务也就完成了,此时就可以进入停止状态。

转载于:https://my.oschina.net/chenzhou/blog/2049677

java高级-多线程编程相关推荐

  1. 西工大java高级网络编程_西工大16春《JAVA高级网络编程》平时作业

    西工大16春<JAVA高级网络编程>平时作业 7 o& [9 w  ^# D  Z一.单选题:[25道,总分:100分]5 z# ?* Z! M% M1 h4 R# n. D+ a ...

  2. 课工场-JAVA高级特性编程及实战第1章练习题3答案参考

    JAVA高级特性编程及实战第1章练习题3答案参考~ 本人菜鸟,一章章地学, 本想在网上搜一下然后对下答案的, 没找着~ 本着虔诚的心,把自己做的贴出来~ 运行结果是了出来了,过程不知道是否正确 欢迎大 ...

  3. 用10086客服热线理解Java高级多线程之线程池

    Java高级多线程之线程池 客服热线案例 引入线程池 1.线程的概念 2.线程池的作用: 获取线程池 1.常用的线程池接口和类 2.代码案例 Callable接口 1.概念简述 2.应用场景 3.方法 ...

  4. Java高级特性编程及事件_java高级特性是什么

    详细内容 java高级特性主要有集合框架及泛型,实用类,输入和输出处理,注解与多线程,网络编程与XML技术. 集合框架 是一套性能优良.使用方便的接口和类(位于java.util包中)解决数组在存储上 ...

  5. C++高级——多线程编程

    目录 线程 怎么创建启动一个线程 线程如何区分 线程如何结束 主线程如何处理子线程 多线程编程 锁 CAS原子操作 lock_guard和unique_lock 线程通信--生产者消费者模型 线程中只 ...

  6. 【JAVA】多线程编程实现实例(全面实现)

    首先,我们我们要进行多线程编程,最少线程怎么创建时最基本的知识. 创建线程由四种方式 1.继承Thread类创建线程(重写run方法,用start()开启线程) 2.实现Runable接口创建线程(重 ...

  7. 西工大java高级网络编程_奥鹏西工大16春《JAVA高级网络编程》平时作业

    西工大16春<JV高级网络编程>平时作业 一.单选题(共 25 道试题,共 100 分.) 1. 假设以tomt为w服务器,在hllopp应用中有一个hllo.jsp,它的文件路径如下: ...

  8. Java 高级 --- 多线程快速入门

    这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 多线程快速入门 1.线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组 ...

  9. java中多线程编程案例_Java中多线程编程实战的实现线程_Java编程_Java程序员_课课家...

    java编程语言使多线程如此简单有效,以致于某些程序员说它实际上是自然的.尽管在 Java 中使用线程比在其他语言中要容易得多,仍然有一些概念需要掌握.要记住的一件重要的事情是 main() 函数也是 ...

最新文章

  1. 【Qt】通过QtCreator源码学习Qt(一):pro文件
  2. Kubernetes 弹性伸缩全场景解读(五) - 定时伸缩组件发布与开源
  3. delphi中move函数的用法
  4. linux 命令 全程,linux命令及全程详解
  5. 不常见但是有用的 Chrome 调试技巧
  6. Linux里sra文件是什么,prefetch命令下载SRA文件
  7. Spring-发送QQ邮件
  8. rmi 反序列化漏洞_写一个rmi反序列化工具
  9. 50岁开始学python_再过两年C语言就50岁了,这么老的编程语言怎么还没有过时?...
  10. Windows Server已可安装Docker,Azure开始支持Mesosphere
  11. 2021五一建模a题完整论文
  12. 模拟电子技术基础简明课程(第三版)思维导图
  13. 快速解决cmd命令行乱码问题
  14. VMware虚拟机安装Windows Server 2008 R2
  15. Kindle4rss中文rss资源推荐~
  16. 元宇宙终极目标是打造六界
  17. 【观察】新华三:云智原生,重塑未来
  18. YY语音无有效验证导致下载执行任意程序
  19. 软件发明专利实例_申请软件发明专利的一些案例
  20. 白色相簿2 coda篇各结局概率分析

热门文章

  1. boost::core模块实现范围枚举C++11
  2. boost::convert模块实现lexical_cast的测试程序
  3. VTK:可视化之Hanoi
  4. VTK:网格之CellEdges
  5. VTK:Medical之TissueLens
  6. VTK:图表之ColorVertexLabels
  7. Qt Creator分析QML应用程序
  8. OpenGL 高级GLSL(Advanced GLSL)
  9. C语言实现hashset算法(附完整源码)
  10. C语言函数——常用数学函数