JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口
JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口
开始挑战一些难度了,线程和I/O方面的操作了,继续坚持
一.Thread
如何在自定义的代码中,自定义一个线程呢?
我们查看API文档,我们要启动一个线程,先实现一个子类,
package com.lgl.hellojava;
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("我是一个线程");
}
}
我们要调用它的话,只需要start就可以
MyThread thread = new MyThread();
thread.start();
这样就会执行我们的run方法
我们来理一下思路,线程有两种创建方式,我们先将第一种:
- 1.继承Thread 类
- 2.复写Thread类的run方法
- 3.调用线程的start方法
- 该方法有两个作用,启动线程和调用run方法
我们可以把代码改一下
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
for (int i = 0; i < 1140; i++) {
System.out.println("Hello JAVA");
}
}
}
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1140; i++) {
System.out.println("我是一个线程");
}
}
}
这样输出多少?
你注意一下,他们交叉输出了,这种,就是多线成,两个线程同时在跑,都在获取cpu的使用权,cpu执行到谁,谁就执行,明确一点,在某一个时刻,只能有一个程序在运行(多核除外),cpu在做着快速的切换以达到看上去是同时运行的效果
我们可以形象的把多线成的运行,形容为在互相抢夺CPU的资源,那么这就是多线成的一个特性叫随机性,谁抢到谁执行,但是执行多长,cpu说了算
二.run和start的特点
为什么要覆盖run方法
Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法
也就是说Thread类汇总的run方法是用于存储线程执行的代码
目的:将自定义的代码存储在run方法中让线程运行
三.线程运行状态
线程运行会有几种状态,我们要了解他的状态,才能了解他运行的原理,我们先来看一张图
我们一步步来分析,首先线程的第一种状态是创建,你new一个线程就是被创建了,紧接着,就是运行的状态,他们的过程,就是start,当然,线程还有一种为冻结,处于某一种状态,就交冻结,他们通过sleep来交替。最后就是线程结束了,通过stop,当然,还有其他一些状态,比如阻塞,这是临时状态,这是具备运行资格,但是没有执行权
四.获取线程对象和名称
线程都是有名称的,通过格式Thread-编号来区分,我们可以这样来验证
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程名称:"+this.getName());
}
}
它输出的结果就是
他是从0开始,当然,他既然有getrName,那肯定有setName方法,其实他初始化的时候就有方法,父类已经给我们提供好了
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
MyThread thread = new MyThread("hello");
thread.start();
}
}
class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println("线程名称:"+this.getName());
}
}
那么我们输出的结果
它还可以通过Thread.currentThread()来获取对象名称,它等同于this.getName();
五.多线程实例演示
我们来一个简单的实例来结束本篇blog,那就是卖票了,很多窗口都能卖票,这就是同时运行
package com.lgl.hellojava;
import javax.security.auth.callback.TextInputCallback;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
/**
* 需求:简单的卖票程序,多个线程同时卖票
*/
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
MyThread my3 = new MyThread();
MyThread my4 = new MyThread();
my1.start();
my2.start();
my3.start();
my4.start();
}
}
/**
* 卖票程序
*
* @author LGL
*
*/
class MyThread extends Thread {
// 票数
private int tick = 100;
@Override
public void run() {
while (true) {
if (tick > 0) {
System.out.println(currentThread().getName()+"卖票:" + tick--);
}
}
}
}
我们这样就实现了票卖了,但是这里出了一个问题,四个线程,他一共卖了400张票,那可不行,火车就一百张票,这是不符合规则的,我们需要怎么改?让四个对象共享一个票数,那我们就需要静态了
// 票数
private static int tick = 100;
但是我们一般不定义静态,他的生命周期有点长,我们换一种角度考虑,其实这就关乎到创建方法了,我们在之前就讲个,线程创建有两种方法。
六.Runnable接口
我们需要使用第二种方法,所以是这样写的,实现Runnable的接口
package com.lgl.hellojava;
import javax.security.auth.callback.TextInputCallback;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
/**
* 需求:简单的卖票程序,多个线程同时卖票
*/
MyThread myThread = new MyThread();
Thread t1 = new Thread(myThread);
Thread t2 = new Thread(myThread);
Thread t3 = new Thread(myThread);
Thread t4 = new Thread(myThread);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/**
* 卖票程序
*
* @author LGL
*
*/
class MyThread implements Runnable {
// 票数
private int tick = 100;
@Override
public void run() {
while (true) {
if (tick > 0) {
System.out.println("卖票:" + tick--);
}
}
}
}
我们得到的输出结果就正确了
创建线程的第二种方式,实现Runnable接口
- 1.定义类实现Runnable接口
- 2.覆盖Runnable接口的run方法
- 将线程要运行的代码存放在该run方法中
- 3.通过Thread类建立线程对象
- 4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
- 为什么要将Runnable接口的子类对象传递给Thread的构造函数,因为,自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去指定对象的run方法,就必须明确该run方法所属的对象
- 5.调用Thread类的start方法开启线程并调用Runnable接口的run方法
这两种方式有什么区别呢?
- 实现方式好处,避免了单继承的局限性,在定义线程时,建议使用实现方式
- 线程代码存放的位置不一样
小伙伴们有没有对线程了解的更深刻一点呢?不明白没关系,我们下篇还是接着讲线程,如果有兴趣可以加入群:555974449,欢迎一起交流
JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口的更多相关文章
- JAVA之旅(二十九)——文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习
JAVA之旅(二十九)--文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习 我们继续学习File 一.文件递归 我们可以来实现 ...
- JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤
JAVA之旅(二十八)--File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤 我们可以继续了,今天说下File 一.File概述 文件的操作是非常 ...
- JAVA之旅(二十六)——装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片
JAVA之旅(二十六)--装饰设计模式,继承和装饰的区别,LineNumberReader,自定义LineNumberReader,字节流读取操作,I/O复制图片 一.装饰设计模式 其实我们自定义re ...
- JAVA之旅(二十五)——文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine
JAVA之旅(二十五)--文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine 我们继续IO上个篇 ...
- JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习
JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了 ...
- JAVA之旅(二十二)——Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习
JAVA之旅(二十二)--Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习 继续坚持下去吧,各位骚年们! 事实上,我们的数据结构,只剩下这个Map的知识点了,平时开发中 ...
- JAVA之旅(二十)—HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习
JAVA之旅(二十)-HashSet,自定义存储对象,TreeSet,二叉树,实现Comparator方式排序,TreeSet小练习 我们继续说一下集合框架 Set:元素是无序(存入和取出的顺序不一定 ...
- 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条
http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...
- JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
JAVA之旅(二十一)--泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符 不知不觉JAVA之旅已经写到21篇了,不得不感叹当初自己坚持要重学一遍JAVA的信念,中途也算 ...
随机推荐
- js密码64加密
可以在客户端对密码进行简单的64位加密,服务端对应使用64位解密即可. /** * * Base64 encode / decode * * @author * @date * @email */ f ...
- Python中enumerate用法详解
enumerate()是python的内置函数.适用于python2.x和python3.xenumerate在字典上是枚举.列举的意思enumerate参数为可遍历/可迭代的对象(如列表.字符串)e ...
- delphi 线程教学第六节:TList与泛型
第六节: TList 与泛型 TList 是一个重要的容器,用途广泛,配合泛型,更是如虎添翼. 我们先来改进一下带泛型的 TList 基类,以便以后使用. 本例源码下载(delphi XE8版本) ...
- LintCode题解之统计数字
直接硬搜就可以了,只是需要考虑k为0的情况. public class Solution { /* * @param : An integer * @param : An integer * @ret ...
- Java第8次实验(IO流)
参考资料 本次作业参考文件 正则表达式参考资料 第1次实验 1. 字符流与文本文件:使用 PrintWriter(写),BufferedReader(读) 参考文件:基础代码目录Student.jav ...
- Rails多路径调用相同方法原路返回的方法
有时候可能有多条path到达同一个method,此时,我们希望在该方法完成后自动转到之前进入的path中去,其实实现起来非常简单,只需要实现如下两个方法: def redirect_back_or(d ...
- NLP系列(5)_从朴素贝叶斯到N-gram语言模型
作者: 龙心尘 && 寒小阳 时间:2016年2月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50646528 ...
- 安卓7.1 新特性Shortcut
介绍 Shortcut 是谷歌在API25提出来的 类似苹果3D touch 但是没有压力感应.在安卓中完全就是长按. 来看下效果吧: 是不是很赞? 那么请随本文一起学习吧 更新 新建项目 在你项目下 ...
- [图论]最大流问题(Maximum flow)的定义
首先定义网络(network)N =(V,E), V表示顶点(Vertices)集合, E表示边(Edges)集合. s,t是V中的两个顶点,分别表示网络N中的源点(source)和汇点(sink). ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(1)——简介
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 在工作中发现有不少类似的现象,有幸看到国外大牛写的一篇文章,由于已经完善得不能再添油加醋,所以决定直接翻译,原文出处:http ...