Java并发编程(6):Runnable和Thread实现多线程的区别(含代码)
Java中实现多线程有两种方法:继承Thread类、实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下优势:
1、可以避免由于Java的单继承特性而带来的局限;
2、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;
3、适合多个相同程序代码的线程区处理同一资源的情况。
下面以典型的买票程序(基本都是以这个为例子)为例,来说明二者的区别。
首先通过继承Thread类实现,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class MyThread extends Thread{
private int ticket = 5 ;
public void run(){
for ( int i= 0 ;i< 10 ;i++)
{
if (ticket > 0 ){
System.out.println( "ticket = " + ticket--);
}
}
}
}
public class ThreadDemo{
public static void main(String[] args){
new MyThread().start();
new MyThread().start();
new MyThread().start();
}
}
|
某次的执行结果如下:
从结果中可以看出,每个线程单独卖了5张票,即独立地完成了买票的任务,但实际应用中,比如火车站售票,需要多个线程去共同完成任务,在本例中,即多个线程共同买5张票。
下面是通过实现Runnable接口实现的多线程程序,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class MyThread implements Runnable{
private int ticket = 5 ;
public void run(){
for ( int i= 0 ;i< 10 ;i++)
{
if (ticket > 0 ){
System.out.println( "ticket = " + ticket--);
}
}
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
|
某次的执行结果如下:
从结果中可以看出,三个线程一共卖了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对象中的代码,不存在多个线程共同执行同一个方法的情况。
from: http://www.importnew.com/20584.html
原文出处: 兰亭风雨
Java并发编程(6):Runnable和Thread实现多线程的区别(含代码)相关推荐
- Java 并发编程系列之带你了解多线程
早期的计算机不包含操作系统,它们从头到尾执行一个程序,这个程序可以访问计算机中的所有资源.在这种情况下,每次都只能运行一个程序,对于昂贵的计算机资源来说是一种严重的浪费. 操作系统出现后,计算机可以运 ...
- 【Java并发编程】:Runnable和Thread实现多线程的区别
Java中实现多线程有两种方法:继承Thread类.实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下 ...
- Java并发编程(一)Thread详解
一.概述 在开始学习Thread之前,我们先来了解一下 线程和进程之间的关系: 线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位. 线程不能够独立执行,必须依存在应用程序中,由应用程 ...
- Java并发编程—说说Runnable与Callable
原文作者:每天一点 原文地址:说说Runnable与Callable 首先,我们先看看使用Callable创建线程与使用Runable的区别: import java.util.concurrent. ...
- Java并发编程举例Runnable, Callable, Future, FutureTask, CompletionService
import java.util.concurrent.*;/*** Created by chenh on 2017/3/23.*/ public class ConcurrentDemo {// ...
- Java并发编程(三)volatile域
相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Android多线程(一)线程池 Android多线程(二)AsyncTask源代码分析 前言 有时仅仅为了读写一个或 ...
- Java并发编程:Thread类的使用
为什么80%的码农都做不了架构师?>>> Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学 ...
- Java并发编程71道面试题及答案
Java并发编程71道面试题及答案 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方 ...
- Java并发编程有多难?这几个核心技术你掌握了吗?
本文主要内容索引 1.Java线程 2.线程模型 3.Java线程池 4.Future(各种Future) 5.Fork/Join框架 6.volatile 7.CAS(原子操作) 8.AQS(并发同 ...
最新文章
- Apache htaccess 重写假设文件存在!
- 0603贴片电阻阻值对照表_怎样读贴片电阻阻值
- php中 elseif和else if 的区别
- HTML5 的知识分享(二):HTML5 的常用标签
- leetcode 108. Convert Sorted Array to Binary Search Tree | 108. 将有序数组转换为二叉搜索树(Java)
- Nignx出现failed (3: The system cannot find the path specified)问题
- deepin终端启动自安装程序
- 【NOIP2017】【Luogu3955】图书管理员(枚举,取模得后缀)
- Oracle DB优化-如何看SQL的执行计划+收集表的统计信息
- 动态心电图信息存储(三)
- 仓库管理无纸化,WMS仓库管理软件+条形码技术
- 专网网速测试软件,CMD怎么测试网速?测网速用命令PING
- lfs库下载_lua使用lfs.dll库进行文件操作
- win7系统如何提升电脑开机速度?
- phpcms V9 模板使用 模板安装 模板怎么用?
- 成为一个大数据开发工程师的学习步骤--文字版
- 【高德地图API】从头德国高中生JS API(三)覆盖物——大喊|折线|多边形|信息表|聚合marker|点蚀图|照片覆盖...
- 汇编-ASCⅡ码转二进制码
- 美肤宝母公司环亚冲刺深交所:年营收超20亿 为胡兴国家族企业
- 【高危】Google Chrome V8 类型混淆漏洞(CVE-2023-2033)
热门文章
- elasticsearch6.X 及head插件部署(完整版)
- CSDN蒋涛大数据表明:DCO - 区块链时代企业级服务的全新机会
- LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用
- GMIS 2017大会Saman Farid演讲:人工智能时代创业者面对的挑战和机会
- 李彦宏:人工智能不是零和游戏
- html中after伪类原理,css伪类before跟after原理与使用(原)
- RocketMQ:Consumer概述及启动流程与消息拉取源码分析
- jsp springmvc 视图解析器_Springmvc中多视图解析器解析问题
- 数据结构与算法笔记(六)—— 冒泡排序
- 学习笔记——os模块常见列表