Java中实现多线程有两种方法:继承Thread类、实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下优势:

1、可以避免由于Java的单继承特性而带来的局限;

2、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;

3、适合多个相同程序代码的线程区处理同一资源的情况。

下面以典型的买票程序(基本都是以这个为例子)为例,来说明二者的区别。

首先通过继承Thread类实现,代码如下:

  1. class MyThread extends Thread{
  2. private int ticket = 5;
  3. public void run(){
  4. for (int i=0;i<10;i++)
  5. {
  6. if(ticket > 0){
  7. System.out.println("ticket = " + ticket--);
  8. }
  9. }
  10. }
  11. }
  12. public class ThreadDemo{
  13. public static void main(String[] args){
  14. new MyThread().start();
  15. new MyThread().start();
  16. new MyThread().start();
  17. }
  18. }

某次的执行结果如下:

从结果中可以看出,每个线程单独卖了5张票,即独立地完成了买票的任务,但实际应用中,比如火车站售票,需要多个线程去共同完成任务,在本例中,即多个线程共同买5张票。

下面是通过实现Runnable接口实现的多线程程序,代码如下:

  1. class MyThread implements Runnable{
  2. private int ticket = 5;
  3. public void run(){
  4. for (int i=0;i<10;i++)
  5. {
  6. if(ticket > 0){
  7. System.out.println("ticket = " + ticket--);
  8. }
  9. }
  10. }
  11. }
  12. public class RunnableDemo{
  13. public static void main(String[] args){
  14. MyThread my = new MyThread();
  15. new Thread(my).start();
  16. new Thread(my).start();
  17. new Thread(my).start();
  18. }
  19. }

某次的执行结果如下:

从结果中可以看出,三个线程一共卖了5张票,即它们共同完成了买票的任务,实现了资源的共享。

针对以上代码补充三点:

1、在第二种方法(Runnable)中,ticket输出的顺序并不是54321,这是因为线程执行的时机难以预测,ticket--并不是原子操作。

2、在第一种方法中,我们new了3个Thread对象,即三个线程分别执行三个对象中的代码,因此便是三个线程去独立地完成卖票的任务;而在第二种方法中,我们同样也new了3个Thread对象,但只有一个Runnable对象,3个Thread对象共享这个Runnable对象中的代码,因此,便会出现3个线程共同完成卖票任务的结果。如果我们new出3个Runnable对象,作为参数分别传入3个Thread对象中,那么3个线程便会独立执行各自Runnable对象中的代码,即3个线程各自卖5张票。

3、在第二种方法中,由于3个Thread对象共同执行一个Runnable对象中的代码,因此可能会造成线程的不安全,比如可能ticket会输出-1(如果我们System.out....语句前加上线程休眠操作,该情况将很有可能出现),这种情况的出现是由于,一个线程在判断ticket为1>0后,还没有来得及减1,另一个线程已经将ticket减1,变为了0,那么接下来之前的线程再将ticket减1,便得到了-1。这就需要加入同步操作(即互斥锁),确保同一时刻只有一个线程在执行每次for循环中的操作。而在第一种方法中,并不需要加入同步操作,因为每个线程执行自己Thread对象中的代码,不存在多个线程共同执行同一个方法的情况。

转载于:https://www.cnblogs.com/web424/p/6807582.html

【Java并发编程】:Runnable和Thread实现多线程的区别相关推荐

  1. Java并发编程(6):Runnable和Thread实现多线程的区别(含代码)

    Java中实现多线程有两种方法:继承Thread类.实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下 ...

  2. Java并发编程实战~Worker Thread模式

    在上一篇文章中,我们介绍了一种最简单的分工模式--Thread-Per-Message 模式,对应到现实世界,其实就是委托代办.这种分工模式如果用 Java Thread 实现,频繁地创建.销毁线程非 ...

  3. Java并发编程(8):多线程环境中安全使用集合API(含代码)

    在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对 ...

  4. Java并发编程的基础-Thread.interrupted

    通过interrupt,设置了一个标识告诉线程可以终止了,线程中还提供了静态方法Thread.interrupted()对设置中断标识的线程复位.比如在上面的案例中,外面的线程调用thread.int ...

  5. Java并发编程—schedule方法和scheduleAtFixedRate方法的区别

    原文作者:一叶丿清风 原文地址:schedule方法和scheduleAtFixedRate方法的区别 schedule方法和scheduleAtFixedRate方法都可以实现任务的延时和不延时执行 ...

  6. # Java 并发编程的艺术(二)

    Java 并发编程的艺术(二) 文章目录 Java 并发编程的艺术(二) 并发编程的挑战 上下文切换 如何减少上下文的切换 死锁 资源限制的挑战 Java 并发机制的底层实现原理 volatile 的 ...

  7. Java并发编程实战基础概要

    文章目录 Java并发编程实战基础概要 开篇 多线程问题有啥难点呢? 为啥要学习并发编程? 并发问题的根源是什么? CPU切换线程执导致的原子性问题是如何发生的? 缓存导致的可见性问题是如何发生的? ...

  8. Java并发编程:Thread类的使用

    为什么80%的码农都做不了架构师?>>>    Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学 ...

  9. java 并发编程多线程_多线程(一)java并发编程基础知识

    线程的应用 如何应用多线程 在 Java 中,有多种方式来实现多线程.继承 Thread 类.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现带 ...

最新文章

  1. 解决在onCreate()过程中获取View的width和Height为0的4种方法
  2. 一个ThreadLocal和面试官大战30个回合
  3. 计算机科学和Python编程导论(一) 计算机相关理论
  4. php 获取月份的数字,PHP 根据月份数字返回月份名称的实现方法
  5. C语言程序设计:现代方法(第2版)第三章全部习题答案
  6. 【Spring注解系列08】@PostConstruct与@PreDestroy
  7. Hibernate 批量插入、更新与删除
  8. java 继承变量_用java中的变量继承
  9. 3 CO配置-企业结构-分配-把公司代码分配给成本控制范围
  10. mfc 更新服务器文件,MFC程序版本自动升级更新
  11. OpenShift 4 之运行Istio的BookInfo微服务应用
  12. mybatis传入参数类型parameterType详解
  13. kali foremost 分离文件_软件架构之分离关注点
  14. k9s加速k8s集群管理
  15. 小米android的手机根目录,手机网站根目录在哪?
  16. 高仿QQ游戏大厅-支持换肤和控件切换动画
  17. windows Mac 虚拟机显示模糊的问题
  18. mysql chm 文档_最简单,最实用的数据库CHM文档生成工具——DBCHM
  19. AntV-G6实现微服务拓扑图
  20. su和su-以及sudo的理解

热门文章

  1. RNA在相分离中的作用RNA buffers the phase separation behavior of prion-like RNA- binding proteins
  2. R语言重抽样与自助法
  3. 用数据追女神:追女生如同创业
  4. github删除文件_Linux环境下Github操作指南
  5. python读取数据库数据释放内存_在使用python处理数据时,为什么其内存无法自动释放掉?...
  6. php include_once 路径,php使用include加密路径的方法介绍
  7. Spring 框架蕴含的设计思想
  8. Java为何能一次编写,到处运行
  9. Linux嵌入式开发_修改机器码
  10. 基于Opencv的手写字识别