细说多线程之Thread与Runnable
1:创建线程的两种方式:
继承Thread类
public class MyThread extends Thread { @Override public void run() { } } MyThread mt1 = new MyThread(); mt1.start();
public class MyThread implements Runnable { @Override public void run() { } } MyThread mt = new MyThread(); Thread th1 = new Thread(mt); th1.start();
Runnable方式可以避免有thread方式有java单继承特性带来的缺陷
Runnable方式可以被多个线程实例所共享,适合多个线程处理同一资源的情况

public class MyThread extends Thread { /** 一共有5张火车票 */ private int ticketsCont = 5; /** 窗口,也即是线程的名字 */ private String name; public MyThread(String name){ this.name = name; } /** * 写买票逻辑 */ @Override public void run() { while(ticketsCont > 0 ){ // 如果还有票,就卖掉一张 ticketsCont--; System.out.println(name + "卖了1张票,剩余票数为:"+ticketsCont); } }}
MyThread mt1 = new MyThread();
mt1.start();


public class MyThread implements Runnable { /** 一共有5张火车票 */ private int ticketsCont = 5; /** * 写买票逻辑 */ @Override public void run() { while(ticketsCont > 0 ){ // 如果还有票,就卖掉一张 ticketsCont--; System.out.println(Thread.currentThread().getName() + "卖了1张票,剩余票数为:"+ticketsCont); } }}
MyThread mt = new MyThread();
//创建三个线程,模拟三个窗口卖票
Thread th1 = new Thread(mt,"窗口1");
Thread th2 = new Thread(mt,"窗口2");
Thread th3 = new Thread(mt,"窗口3");
// 启动这三个线程,即窗口开始卖票
th1.start();
th2.start();
th3.start();


运行:处于就绪状态的线程,一旦获取了CPU资源,便进入到运行状态,开始执行run()方法里面的逻辑
终止:线程的run()方法执行完毕,或者线程调用了stop()方法,线程便进入终止状态。
阻塞:一个正在执行的线程在某些情况下,由于某种原因而暂时让出了CPU资源,暂停了自己的执行,便进入了阻塞状态,如调用了sleep()方法。
4:线程的分类
用户线程:运行在前台,执行具体任务
守护线程:运行在后台,为其他前台线程服务。一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作(如数据库连接池中的监测线程,JVM启动后的检测线程)
守护线程的设置,必须在start()方法前调用setDaemon(true)设置当前线程为守护线程,否则会抛出IllegalThreadStateException异常;守护线程中产生的线程也是守护线程;不是所有的任务都可以分配给守护线程来执行如读写,计算逻辑等(因为守护线程会在用户线程结束后结束)。
5:守护线程例子
DaemonThread类

public class DaemonThread implements Runnable { @Override public void run() { System.out.println("进入守护线程" + Thread.currentThread().getName()); try { writeToFile(); } catch (Exception e) { System.out.println("守护线程异常:" + e); } System.out.println("退出守护线程" + Thread.currentThread().getName()); } private void writeToFile() throws Exception{ File fileName = new File("d:" + File.separator + "daemon.txt"); // 向文件中追加数据 OutputStream os = new FileOutputStream(fileName,true); int count = 0; int totalCount = 999; while(count < totalCount){ os.write(("\r\nword" + count).getBytes()); System.out.println("守护线程" + Thread.currentThread().getName() + "向文件中写入了word" + count); count++; // 线程休眠1秒 Thread.sleep(1000); } os.close(); }


public static void main(String[] args) {
System.out.println("进入主线程" + Thread.currentThread().getName());
DaemonThread daemonThread=new DaemonThread();
Thread th1 = new Thread(daemonThread);
th1.setDaemon(true)
th1.start();
Scanner sc = new Scanner(System.in);
sc.next();
sc.close();
executor.shutdownNow();
System.out.println("退出主线程" + Thread.currentThread().getName());
}

6:jstack工具:(是window自带工具,在命令行直接可以使用)
作用:生成JVM当前时刻线程快照,即当前进程所有线程消息。
目的:帮助定位程序问题出现的原因,如长时间停顿、CPU占用率过高等。
使用:在命令行输入jstack pid(进程id,在任务管理器中可以查看到)
细说多线程之Thread与Runnable的更多相关文章
- 慕课网_细说多线程之Thread VS Runnable
第1章 课前准备 1-1 前言 (00:49) 第2章 Thread VS Runnable 2-1 回顾线程创建的两种方式 (02:33) 继承Thread类 class MyThread exte ...
- 细说多线程之Thread VS Runnable
[线程创建的两种方式] [线程的生命周期] ● 就绪:创建了线程对象后,调用了线程的start(). (注意:此时线程只是进入了线程队列,等待获取CPU服务,具备了运行的条件,但并不一定已经开始运行了 ...
- Java多线程之Thread、Runnable、Callable及线程池
一.多线程 线程是指进程中的一个执行流程,一个进程中可以有多个线程.如java.exe进程中可以运行很多线程.进程是运行中的程序,是内存等资源的集合,线程是属于某个进程的,进程中的多个线程共享进程中的 ...
- 三、多线程之Thread与Runnable的区别
Thread与Runnable的区别(用三个窗口同时出售10张车票为例子) 运行代码 运行结果 分析 System.out.println("开始测试多线程");class MyT ...
- Android线程之Thread 、Runnable 的两个例子
Thread例子: package fy.test; import android.app.Activity; import android.os.Bundle; import android.os. ...
- 多线程编程(三)--创建线程之Thread VS Runnable
前面写过一篇基础的创建多线程的博文: 那么本篇博文主要来对照一下这两种创建线程的差别. 继承Thread类: 还拿上篇博客的样例来说: 四个线程各自卖各自的票,说明四个线程之间没有共享,是独立的线程. ...
- 多线程之thread和runnable
Runnanle方式可以避免Thread由于单继承特性带来的缺陷. Runnable代码可以被多个线程(thread实例)共享,适用于多个线程处理同一资源的情况. 线程的生命周期:创建,就绪,阻塞,运 ...
- Java基础-进程与线程之Thread类详解
Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...
- iOS多线程之Thread
多线程 • Thread 是苹果官方提供的,简单已用,可以直接操作线程对象.不过需要程序员自己管理线程的生命周期,主要是创建那部分 优缺点 面向对象,简单易用 直接操作线程对象 需要自己管理线程生命周 ...
随机推荐
- [转]Tomcat优化之内存、并发、缓存
1.Tomcat内存优化 Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh 中设置 JAVA_OPTS 参数. JAVA_OPTS ...
- vue授权页面登陆之后返回之前的页面
import Vue from 'vue'import Router from 'vue-router'Vue.use(Router)import home from "@/pages/ho ...
- IS Decisions如何帮助企业提高安全标准
PCI DSS标准有什么要求? 简单地说,PCI DSS要求最高级别的网络安全性.这一标准如今广泛应用于需要存储.管理.传输客户(或持卡人)个人数据的行业和领域. 施行严格的访问监控措施 为了保证关键 ...
- 20_AOP_Advice增强1(前置、后置、环绕)
[增强的类型] 1.前置增强:org.springframework.aop.BeforeAdvice. 由于Spring只支持方法级别的增强,所以MethodBeforeAdvice是目前可用的前置 ...
- ArcMap没有工具条和菜单栏的解决方法
问题: 在安装ArcGIS10后,打开竟然没有菜单栏和工具栏,安装10.1又有,卸了重装10还是没有 解决办法: 在ArcMap的状态栏上双击,在弹出的自定义对话框中,在Toolbars工具栏选择Ma ...
- Oracle:environment variable "PATH" does not exceed the recommended length
今天重新安装oracle11g,突然在检测时报了以下错误: Environment variable: "PATH" - This test checks whether the ...
- Python 基于固定 IP 来命名 ARM 虚拟机的实现
问题描述 希望通过 Python 批量创建 ARM 虚拟机,并且在虚拟机命名时加入固定 IP 信息,方便管理维护. 问题分析 在创建 ARM 虚拟机之前,先创建固定 IP,然后获取固定 IP 地址,创 ...
- win10与子系统ubuntu之间互访文件
在window10的store里面 搜索ubuntu,下载,可以安装 注意: 初次打开有许多软件都没安装,可以新进行 sudo apt-get update,之后在进行其他的操作 1.下载的子系统ub ...
- 源码安装mysql,及主从同步
源码安装mysql [可选] 如果用源码安装cmake软件: cd /home/oldboy/tools/ tar xf cmake-.tar.gz cd cmake- ./configure #CM ...
- 确定浏览器是否支持某些DOM模块
var supportDOM2Core = document.implementation.hasFeature("Core","2.0"); var supp ...