实战录》导语

一转眼作为一名Java开发者已经四年多时间了,说长不长说短不短,对于java的感情还是比较深的,主要嘛毕竟它给了我饭吃。哈哈,开个玩笑。今天我想借此机会来和大家聊聊Java多线程。文中若有错误还请各位小伙伴及时指出。

Java是一种跨平台,适合于分布式计算环境的面向对象编程语言。关于Java的优点,我想每个刚接触Java的朋友,都会听过你的Java启蒙老师说过这么一句话:“一次编译,到处运行”。这个“到处运行”是说任何平台上只要安装了JRE,就可以运行已经编译过的(不管是什么环境编译的)Java程序。

既然Java 这么厉害,那么想要知道为什么厉害肯定是要知道他的优点嘛。那么我们就去体验下Java的高级特性。Java主要高级特性有1.线程 2.IO 3.类集 4.反射(排名不分先后)等等。今天我想借此机会来和大家聊聊Java多线程。文中若有错误还请各位小伙伴及时指出。

了解一样东西,我时常会关心的问题基本和刘姥姥进大观园一样。二点 1.它是什么?(多线程是啥?) 2.它可以做什么?(多线程在什么样的场景下使用?怎么去用?)

它是什么?

1.1进程和线程的概念

进程:运行中的应用程序称为进程,拥有系统资源(cpu、内存)。

线程:进程中的一段代码,一个进程中可以有多段代码。本身不拥有资源(共享所在进程的资源)。举个例子:假如我们都是工地搬砖工,我们每天都要不停的把砖搬上卡车(排队依次放砖),我们排队放砖(循环的排队,一直排下去,直到我不想干了离职,退出),每个搬砖工都有机会到达队伍的最前端把砖头放入卡车,这个就好比是线程,都有机会被程序执行。但是线程真正起作用的时候,就是我们在队伍的把砖头放入卡车,这一段时间,这是线程真正执行的阶段。

在java中,程序入口被自动创建为主线程,在主线程中可以创建多个子线程。

两者的区别

1、是否占有资源问题。 2、创建或撤销一个进程所需要的开销比创建或撤销一个线程所需要的开销大。 3、进程为重量级组件,线程为轻量级组件

多进程: 在操作系统中能同时运行多个任务(程序)。多线程: 在同一应用程序中有多个功能流同时执行。

1.2线程的主要特点

①、不能以一个文件名的方式独立存在在磁盘中;②、不能单独执行,只有在进程启动后才可启动;③、线程可以共享进程相同的内存(代码与数据)。既然可以共享相同内存,这边就会有个数据一致性的问题。

1.3 线程的主要用途

①、利用它可以完成重复性的工作(如每天闹钟时间的提醒)。②、从事一次性较费时的初始化工作(如网络连接、Web服务中加载一些菜单权限等)。③、并发执行的运行效果(一个进程多个线程)以实现更复杂的功能

1.4、多线程(多个线程同时运行)程序的主要优点

①、可以减轻系统性能方面的瓶颈,因为可以并行操作;②、提高CPU的处理器的效率,在多线程中,通过优先级管理,可以使重要的程序优先操作,提高了任务管理的灵活性;另一方面,在多CPU系统中,可以把不同的线程在不同的CPU中执行,真正做到同时处理多任务。

以上说明了线程的基本概念。那么接下来就用代码来说明几个小例子看下多线程在什么样的场景下使用?怎么去用?

它可以做什么?

java中创建一个线程有两种方式:

1、继承Thread类,重写run方法,然后直接new这个对象的实例,创建一个线程的实例。然后调用start方法启动线程。2、实现Runnable接口,重写run方法,然后调用new Thread(runnable)的方式创建一个线程,然后调用start方法启动线程。

对于这两种方式的区别是:

继承Thread:线程代码存放Thread子类run方法中。实现Runnable,线程代码存在接口的子类的run方法。实现Runnable接口相对于继承Thread类来说,有如下的显著优势:

1.适合多个相同代码的线程去处理同一个资源的情况2.可以避免由于java的单继承特性带来的局限3.增强了程序的健壮性,代码能够被多个线程共享,代码与数据时独立的

看个有趣的例子,对比如下:

场景:某建筑工地包工头新进一批砖头有15W块,要从A地点搬到B地点。假设工地上有三个工人(看做线程哦),每天工人推板车拉砖的次数是5次,每次一车假设可以拉1W。包工头很人性化平均分道每个人头上5W砖。我们来看下非常有趣的Java代码。

A.继承Thread方式Code:

//新建一个搬砖仔的线程public class BanZhuanThread extends Thread { //工人名字 private String name;

public BanZhuanThread(String name) { this.name = name; } //砖头块数5W 老板分的很均匀,人很好! private int bricks = 5; @Override public void run { for(int i=0 ;i<5;i++) { System.out.println(name + "正在搬砖! 剩余砖头 " + bricks-- +"万"); if(i==4) { System.out.println("我是"+name+",活干完了,下班"); } } }}

//新建三个工人去搬砖,分别新建三个工人线程大强,小强,中强去搬砖

public class TestThread { public static void main(String args) { Thread catThread = new BanZhuanThread("小强"); catThread.start;

Thread catThread2 = new BanZhuanThread("大强"); catThread2.start;

Thread catThread3 = new BanZhuanThread("中强"); catThread3.start;

}}

//结果输出大强正在搬砖! 剩余砖头 5万大强正在搬砖! 剩余砖头 4万大强正在搬砖! 剩余砖头 3万大强正在搬砖! 剩余砖头 2万大强正在搬砖! 剩余砖头 1万我是大强,活干完了,下班中强正在搬砖! 剩余砖头 5万中强正在搬砖! 剩余砖头 4万中强正在搬砖! 剩余砖头 3万中强正在搬砖! 剩余砖头 2万中强正在搬砖! 剩余砖头 1万我是中强,活干完了,下班小强正在搬砖! 剩余砖头 5万小强正在搬砖! 剩余砖头 4万小强正在搬砖! 剩余砖头 3万小强正在搬砖! 剩余砖头 2万小强正在搬砖! 剩余砖头 1万我是小强,活干完了,下班

B.实现Runnable接口方式Code:

//新建一个搬砖仔的线程public class BanZhuanRunnable implements Runnable {

//砖头总块数15W ! private int bricks = 15;

@Override public void run { for(int i=0 ;i<5;i++) { System.out.println(Thread.currentThread.getName + "正在搬砖! 剩余砖头 " + bricks-- +"万"); if(i==4) { System.out.println("我是"+Thread.currentThread.getName+",活干完了,下班"); } } }}

//新建三个工人去搬砖,分别新建三个工人线程大强,小强,中强去搬砖public class TestThread { public static void main(String args) {

Runnable catThread = new BanZhuanRunnable; new Thread(catThread,"小强").start; new Thread(catThread,"大强").start; new Thread(catThread,"中强").start; }}

//结果输出小强正在搬砖! 剩余砖头 14万中强正在搬砖! 剩余砖头 13万中强正在搬砖! 剩余砖头 11万中强正在搬砖! 剩余砖头 10万中强正在搬砖! 剩余砖头 9万中强正在搬砖! 剩余砖头 8万我是中强,活干完了,下班大强正在搬砖! 剩余砖头 15万小强正在搬砖! 剩余砖头 12万小强正在搬砖! 剩余砖头 6万小强正在搬砖! 剩余砖头 5万小强正在搬砖! 剩余砖头 4万我是小强,活干完了,下班大强正在搬砖! 剩余砖头 7万大强正在搬砖! 剩余砖头 3万大强正在搬砖! 剩余砖头 2万大强正在搬砖! 剩余砖头 1万我是大强,活干完了,下班

看完以上代码我们可以发现在实现Runnable接口方式Code中验证了适合多个相同代码的线程去处理同一个资源(砖块)的情况。而不是像继承Thread方式Code中那样先分割。

PS:既然是共享的资源变量,那么如Runnable接口方式Code中的private int bricks = 15;就会有线程安全问题。所以如果在数据量大的情况Runnable接口方式Code代码是有一定问题的。但是从中已经可以看出他们之间的区别。如果看完还是没感觉自己敲一把体验下那个包工头的例子。

总结

由于篇幅有限,上面只是简单介绍了下Java中怎么创建线程以及基本的使用,但是已经可以体会到多线程的乐趣所在。上述列子也反映出了多线程过程中对共享资源的线程安全问题。解决这种问题就会引出锁的感念,以及多线程下怎么性能的优化。

最后说下本人对于多线程使用场景的一些经验。

1.如果你的一个大任务可以分成多个独立的并且互不影响的并且重复度极高子任务的话。那么大胆用多线程去做吧。控制好内存中线程数等问题。2.特别耗时的操作,如备份数据库,可以开个线程执行备份,然后执行返回,前台不断向后台询问线程执行状。3.需要异步处理的时候,需要使用多线程。4.对于多线程中,执行失败的时候尽可能要有补偿机制。哪怕是写日志记录也可以。

说着说着就想不到了。。。。。先这样吧。-.-!

云端卫士实战录 | Java高级特性之多线程的更多相关文章

  1. paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  2. Java高级特性-String、StringBuffer和StringBuilder

    Java高级特性-String.StringBuffer和StringBuilder String Java语言中的字符串值都属于String类,虽然有其他方法表示字符串(如字符串数组),但Java一 ...

  3. java高级特性增强

    第4天 java高级特性增强 今天内容安排: 1.掌握多线程 2.掌握并发包下的队列 3.了解JMS 4.掌握JVM技术 5.掌握反射和动态代理 java多线程增强 .1. java多线程基本知识 . ...

  4. Java高级特性——反射机制(第二篇)

    在Java高级特性——反射机制(第一篇)中,写了很多反射的实例,可能对于Class的了解还是有点迷糊,那么我们试着从内存角度去分析一下. Java内存 从上图可以看出,Java将内存分为堆.栈.方法区 ...

  5. Java高级特性1_流库_初体验

    Java高级特性流库_初体验 面对结果编程 在编程里, 有两种编程方式, 一种是面对过程编程, 一种是面对结果编程. 两者区别如下 面向过程编程 面向过程编程需要编程程序让程序依次执行得到自己想要的结 ...

  6. Java高级特性之泛型

    首先我们先提出两个问题: 什么是泛型? 为什么要使用泛型?我们先来看看第一个问题什么是泛型.如果你对Java三大特性中的多态性理解的比较透彻的话,泛型就比较好理解了.多态性表示一个对象具备多种状态.比 ...

  7. 问题集录--Java高级软件工程师面试考纲(转)

    如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构.算法.网络.操作系统等知识.因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对 ...

  8. Java高级特性 第7节 多线程

    一.进程与线程的概念 1. 进程 进程是应用程序的执行实例,有独立的内存空间和系统资源. 如上图,标红色的是一个Office Word进程. 进程的特点: 动态性:进程是动态的创建和消亡: 并发性:操 ...

  9. Java高级特性—并发包

    1). java并发包介绍 JDK5.0 以后的版本都引入了高级并发特性,大多数的特性在java.util.concurrent 包中,是专门用于多线程发编程的, 主要包含原子量.并发集合.同步器.可 ...

随机推荐

  1. Json与Bean互转,Timestamp类型的问题

    Json与Java Bean互相转换时,Bean中的Timestamp字段是无法直接处理的,需要实现两个转换器. DateJsonValueProcessor的作用是Bean转换为Json时将Time ...

  2. CentOS安装NodeJS及Express开发框架

    http://zhaohe162.blog.163.com/blog/static/38216797201402234212981/   express 命令行工具 npm install -g ex ...

  3. HDOJ(1115)多边形重心

    Lifting the Stone http://acm.hdu.edu.cn/showproblem.php?pid=1115 题目描述:输入n个顶点(整数),求它们围成的多边形的重心. 算法:以一 ...

  4. 我的第一个WP8.1应用总结

    我的LUMIA925已经买了很久了,想自己开发WP应用放在上面,却一直想不到有什么特别的想法和需要.前几天的事情正好让我有了这个机会. 前几天在客户机房工作的时候,同事打电话来说另一个客户由于换了电脑 ...

  5. 【原】相煎何太急——input的blur事件与button的click事件

    先来一段引子,最近在写手机h5页面,主要是一些登陆注册方面的,最绕不开的就是表单元素. 我想实现的是:在输入框后边有一个删除图标,当输入东西的时候触发事件,显示删除图标,点击该图标会删除之前输入的内容 ...

  6. mave的变量说明

    Maven提供了三个隐式的变量可以用来访问环境变量,POM信息,和Maven Settings env env变量,暴露了你操作系统或者shell的环境变量.便 如在Maven POM中一个对${en ...

  7. Samba 共享文件后在Windows 上无法访问的问题

    /etc/samba/smb.conf的配置如下: #============================ Share Definitions ========================== ...

  8. NFS实践练习

    实践要求: (CentOS 7)两台主机A/B,其中A主机搭建LAMP环境,B主机当做NFS服务器存放Mariadb的数据,并部署Discuz做测试,实现数据库可用. A主机:httpd2.4 php ...

  9. cinder节点部署

    其实看基础理论篇大家也可以看出来,cinder跟nova流程比较像,是这样的,nova为云主机提供了虚拟资源,cinder则是提供存储相关的资源,cinder的小伙伴叫swift,不过这个一般没人用了 ...

  10. git 实用操作

    查看某文件的某些行的变化历史: $ git log --pretty=short -u -L 2003,2005:Executor.cpp http://stackoverflow.com/quest ...