多线程学习-基础(一)Thread和Runnable实现多线程
很久没记录一些技术学习过程了,这周周五的时候偶尔打开“博客园”,忽然让我产生一种重拾记录学习过程的想法,记录下学习研究过程的一点一滴,我相信,慢慢地就进步了!最近想学习一下多线程高并发,但是多线程在实际工作中操刀不多,对于多线程的理解也不够深入,很多地方都存在不确定性,这让我困惑,所以决定从头开始学习一下“多线程”,然后再慢慢研究“高并发”。那么直接记录学习过程吧!
学习或巩固新的知识,需要好的资料和动手去实践,这样效果很明显。
推荐一下我参考的一位博主的博客:https://www.cnblogs.com/yjd_hycf_space/p/7526608.html
那么开始正式记录
一、进程和线程的区别
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
多进程是指操作系统能同时运行多个任务(程序)。
多线程是指在同一程序中有多个顺序流在执行。
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口.
二、扩展java.lang.Thread类
简单例子:
创建一个线程类:
package com.jason.threads;
/**
* 多线程学习(一)1.1
* @function 多线程-继承Tread类来实现多线程
* @author 小风微凉
* @time 2018-4-21 上午10:10:09
*/
public class Thread_1_Action extends Thread {
private String thname;
public Thread_1_Action(String name){
this.thname=name;
}
public void run(){
for(int i=0;i<5;i++){
System.out.println(thname+"运行:"+i);
try {
sleep((int) (Math.random()*10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行线程:
package com.jason.start;
import com.jason.threads.Thread_1_Action;
public class StartAction_1 {
/**
* 测试:多线程继承Thread类
* @param args
*/
public static void main(String[] args) {
Thread_1_Action thread1=new Thread_1_Action("1号线程");
Thread_1_Action thread2=new Thread_1_Action("2号线程");
thread1.start();
thread2.start();
}
}
执行结果:
2号线程运行:0
1号线程运行:0
2号线程运行:1
2号线程运行:2
1号线程运行:1
1号线程运行:2
2号线程运行:3
1号线程运行:3
2号线程运行:4
1号线程运行:4
分析总结: /**
* 总结:
* 进程:操作系统(OS)资源分配的最小单位
* 线程:cpu可调度的最小单位,多个线程共享所在进程的资源。
* 不论进程、线程都有5个状态:创建-就绪-运行-阻塞-终止
* (1)一个线程的start()方法被调用,并不意味着这个线程就会立马被cpu调用,而是由创建状态转变成可执行状态(也即:就绪状态)。
* (2)多个线程的被cpu调用的顺序是不固定的,为乱序执行,这个要操作系统来决定。
* (3)Thread.sleep()方法的目的是为了避免让一个线程持续占用cpu的资源,以空出资源给其他线程来使用。
* (4)多线程的执行顺序每次都是不同的,乱序执行。
* (5)只有乱序执行的代码才有必要设计为多线程。
* (6)一个线程调用了start()方法后,如果再次去调用start(),会抛出java.lang.IllegalThreadStateException异常
*/
三、实现java.lang.Runnable接口
采用Runnable也是非常常见的一种,我们只需要重写run方法即可。下面也来看个实例。
简单例子:
创建一个Java类实现Runnable接口,并实现run()方法
package com.jason.threads;
/**
* 多线程学习(一)1.2
* @function 多线程-实现Runnable接口来实现多线程
* @author 小风微凉
* @time 2018-4-21 上午10:47:55
*/
public class Thread_2_Action implements Runnable{
private String thname;
public Thread_2_Action(String name){
this.thname=name;
}
public void run() {
for(int i=0;i<5;i++){
System.out.println(thname+"运行:"+i);
try {
Thread.sleep((int)Math.random()*10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
执行线程:
package com.jason.start;
import com.jason.threads.Thread_2_Action;
public class StartAction_2 {
/**
* 测试:多线程实现Runnable接口
* @param args
*/
public static void main(String[] args) {
new Thread(new Thread_2_Action("1号线程")).start();
new Thread(new Thread_2_Action("2号线程")).start();
}
}
运行结果:
1号线程运行:0
2号线程运行:0
2号线程运行:1
1号线程运行:1
2号线程运行:2
1号线程运行:2
2号线程运行:3
1号线程运行:3
1号线程运行:4
2号线程运行:4
分析总结:
/**
* 总结:
* (1)Thread_2_Action类通过实现Runnable接口,使得该类有了多线程的特征。
* (2)run()方法是多线程程序的一个约定。所有的多线程代码都在run()方法里面。
* (3)Thread类也是一个实现了Runnable接口的类:class Thread implements Runnable
* 程序说明:
* 在启动多线程的时候,需要通过Thread类的构造器Thread(Runnable target)构造出对象,然后调用Tread对象的start()
* 方法来运行多线程代码。实际上所有的多线程都是通过运行Thread的start()方法来运行的。因此,不管是扩展Thread类还是实现Runnable
* 接口来实现多线程,最终都是Thread对象的API来控制线程的,熟悉Thread类的API是多线程编程的基础。
*/
四、Thread和Runnable的区别
/**
* 总结:Thread和Runnable的区别
* 如果一个类继承了Thread,则不适合资源共享,但是如果实现了Runnable接口的话,则很容易实现资源共享。
* 实现Runnable接口比继承Thread类所具有的优势:
* (1):适合相同的程序代码的线程去处理同一个资源。
* (2):可以避免Java中的单继承限制。
* (3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
* (4):线程池中只能放置实现了Runnable或callable类线程,不能直接放入继承Thread类的线程。
* 特别说明一下:
* main()方法其实也是一个线程。在Java中线程都是同时启动的,至于什么时候,哪个先启动,完全看谁先得到cpu的资源。
* 在Java中,每次执行程序至少要启动2个线程,一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,
* 实际上都会启动一个JVM,每个JVM都会在操作系统(OS)中启动一个进程。
*/
多线程学习-基础(一)Thread和Runnable实现多线程的更多相关文章
- Java - Thread 和 Runnable实现多线程
Java多线程系列--“基础篇”02之 常用的实现多线程的两种方式 概要 本章,我们学习“常用的实现多线程的2种方式”:Thread 和 Runnable.之所以说是常用的,是因为通过还可以通过jav ...
- 多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现
一.多线程模型一:生产者消费者模型 (1)模型图:(从网上找的图,清晰明了) (2)生产者消费者模型原理说明: 这个模型核心是围绕着一个“仓库”的概念,生产者消费者都是围绕着:“仓库”来进行操作, ...
- 多线程学习-基础( 十一)synchronized关键字修饰方法的简单案例
一.本案例设计到的知识点 (1)Object的notify(),notifyAll(),wait()等方法 (2)Thread的sleep(),interrupt(). (3)如何终止线程. (4)如 ...
- 多线程学习-基础( 十)一个synchronized(){/*代码块*/}简单案例分析
一.提出疑惑 上一篇文章中,分析了synchronized关键字的用法.但是好像遗漏了一种情况. 那就是: synchronized(obj){/*同步块代码*/} 一般有以下几种情况: (1)syn ...
- 多线程学习-基础(六)分析wait()-notify()-notifyAll()
一.理解wait()-notify()-notifyAll()obj.wait()与obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,notify是针对已经获 ...
- java多线程机制中的Thread和Runnable()区别
1.java语言使用Thread类及其子类对象来表示线程,新建的一个线程声明周期中经历 新建.(声明一个线程,此时他已经有了相应的内存空间和其他资源),运行(线程创建之久就据用了运行的条件,一旦轮到使 ...
- 多线程学习-基础(四)常用函数说明:sleep-join-yield
一.常用函数的使用 (1)Thread.sleep(long millis):在指定的毫秒内让当前正在执行的线程休眠(暂停执行),休眠时不会释放当前所持有的对象的锁.(2)join():主线程等待子线 ...
- 多线程学习三:Thread API,ThreadLocal,synchronized,volatile和Condition
一.Thread API: setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 首先要了解什么是Thread. ...
- 最简单的java多线程代码(重写thread或者runnable的run方法)
http://blog.csdn.net/testcs_dn/article/details/42526549 java线程使用示例——最简单的线程 线程使用示例一: [java] view plai ...
随机推荐
- IP地址的基础划分
1.基础知识 1.1 IP地址是由网络号(net ID)与主机号(host ID)两部分组成的. 1.2 IP地址的分类 IP地址长度为32位,点分十进制(dotted decimal)地址: 采 ...
- 虚拟环境中的django及相关包安装
1.先进入虚拟环境 pyenv activate virtualenvname. 2.安装django软件包 安装命令: pip install django==1.7 查看安装结果: python ...
- C#中获取Excel文件的第一个表名
// 2.以数据库方式打开并输入数据// 此方式将xls文件所在目录看作数据库,其中的xls文件看作数据库表,表名即文件名(不加扩展名).// 函数importExcelTo ...
- Azure上批量创建OS Disk大于30G的Linux VM
Azure上VM的OS盘的大小在创建时是固定的.Windows是127G,Linux是30G.如果需要批量创建的VM的OS Disk有更大的容量.可以考虑用下面的方法实现. 1 创建一台有Data-d ...
- 二:HTML文本编译器 kindeditor-4.1.10 的使用 SpringMVC+jsp的实现
这和一篇与上一篇的区别在与,上一篇是直接请求到action我们剩下的都是我们全部手动处理, 而这一片篇是由kindeditor内部处理,图片上传到本地,基本上没什么区别,但是有一点一定要注意的就是,这 ...
- 用phpinfo( )打印出来的php版本和在服务器上用php -v打印出来的版本不同的原因
php -v 是linux系统的php版本,而phpinfo里显示的是WEB Server中配置的版本.说简单点,你的系统中有两个php版本. 如果您阅读过此文章有所收获,请为我顶一个,如果文章中有错 ...
- 线程及同步的性能 – 线程池/ ThreadPoolExecutors/ ForkJoinPool
线程池和ThreadPoolExecutors 虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理来自 ...
- throw和throws的区别和联系
突然发现今天诗兴大发,看来又得写点内容了. throw和throws对于Java程序员而言它们真的不是很陌生.但对于我这样的选手而言一提到它们的区别和联系就蒙圈了... 为了以后不蒙圈,今天就研究一下 ...
- 2 ignite关键特性
数据注入和流计算: Ignite流式计算允许以可扩展和容错的方式处理连续不中断的数据流.在一个中等规模的集群中,数据注入Ignite的比例会很高,很容易达到每秒百万级的规模. Ignite可以与主要的 ...
- 使用svn进行本地代码管理
简述 这里讨论的是如何管理自己个人电脑的个人项目的代码.和SVN服务器配置无关. 可以先到TortoiseSVN官网下载安装包进行安装. 代码仓库管理 比如现在有一个工程需要进行管理,可以先将该工程放 ...