java 线程 总结
1.前言
(1)线程的上一级是进程,进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。
(2)线程与进程相似,但线程是一个比进程更小的执行单位,也被称为轻量级进程。一个进程在其执行的过程中可以产生多个线程。
(3)多线程就是多个线程同时运行或交替运行。
(4)提倡多线程而不是多进程 的原因是 线程间的切换和调度的成本远远小于进程。
(5)自定义线程可以继承Thread类 ,或者 实现Runnable接口 。
(6)多进程共享数据导致脏数据,可以使用同步锁 synchronized 解决。
(7)使用 interrupt() 和 return 配合 停止线程。
(8)不是优先级低的线程就一定在优先级高的线程后面运行,而是运行的机率会低一些,,反之亦然。
(9)线程分为用户线程和守护线程 ,当 用户线程 结束后,守护线程跟着结束 ,对于自定义线程可使用方法 setDaemon(true); 设置该线程为守护线程 。
常见的 守护线程是 垃圾回收线程
(10)开启线程的方式一共三种:Thread类、Runnable接口、callable接口
2.自定义线程

package com.example.javabaisc.myThread;
import org.junit.jupiter.api.Test;
public class T1 {
@Test
public void t1(){
//调用方法一
// Mythread m = new Mythread();
// m.start();
//调用方法二
MyRunnable mr = new MyRunnable();
Thread thread=new Thread(mr);
thread.start();
System.out.println("结束");
}
}
//方法一:
class Mythread extends Thread {
@Override
public void run(){
super.run();
System.out.println("我的线程");
}
}
//方法二:
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("使用接口实现我的线程");
}
}
3.多个线程之间不共享变量线程安全的情况
每个线程都有自己的实例变量count ,互不影响

package com.example.javabaisc.myThread; import org.junit.jupiter.api.Test; /**
* 多个线程之间不共享变量线程安全的情况
*/
public class T2 { @Test
public void t2(){
MyThread2 m1 = new MyThread2("1");
MyThread2 m2 = new MyThread2("2");
MyThread2 m3 = new MyThread2("3");
m1.start();
m2.start();
m3.start(); } } class MyThread2 extends Thread {
private int count = 5; MyThread2(String name) {
// super();
//给父类的name属性赋值
this.setName(name);
} //每次new MyThread2只会执行一次run();
@Override
public void run() {
super.run();
while (count>0){
System.out.println("由 线程 " + MyThread2.currentThread().getName() + " 计算,剩余count=" + count);
count--;
}
}
} /*
由 线程 1 计算,剩余count=5
由 线程 1 计算,剩余count=4
由 线程 1 计算,剩余count=3
由 线程 1 计算,剩余count=2
由 线程 1 计算,剩余count=1
由 线程 3 计算,剩余count=5
由 线程 2 计算,剩余count=5
由 线程 3 计算,剩余count=4
由 线程 3 计算,剩余count=3
由 线程 3 计算,剩余count=2
由 线程 3 计算,剩余count=1
由 线程 2 计算,剩余count=4
由 线程 2 计算,剩余count=3
由 线程 2 计算,剩余count=2
由 线程 2 计算,剩余count=1
*/ /*
每个线程都有自己的实例变量count ,互不影响
*/
4.共享数据的情况 [使用 同步锁 可解决脏数据问题]

package com.example.javabaisc.myThread; import org.junit.jupiter.api.Test; /**
* 共享数据的情况 [使用 同步锁 可解决脏数据问题]
*/
public class T3 {
@Test
public void t3() {
MyThread3 myThread3 = new MyThread3();
//参数分别是 自定义线程 ,线程名字
Thread m1 = new Thread(myThread3, "1");
Thread m2 = new Thread(myThread3, "2");
Thread m3 = new Thread(myThread3, "3");
Thread m4 = new Thread(myThread3, "4");
Thread m5 = new Thread(myThread3, "5");
m1.start();
m2.start();
m3.start();
m4.start();
m5.start(); }
} //class MyThread3 extends Thread {
// //公共数据
// private int count = 5;
// //每次new MyThread3只会执行一次run();
// @Override
// public void run() {
// super.run();
// int yu = count--;
// System.out.println("由 线程 " + MyThread3.currentThread().getName() + " 计算,剩余count=" + yu);
//
// }
//} /*
由 线程 3 计算,剩余count=2
由 线程 5 计算,剩余count=3
由 线程 1 计算,剩余count=5
由 线程 4 计算,剩余count=1
由 线程 2 计算,剩余count=4
*/ /*
本应该剩余count是依次递减的 ,可是显示是乱数据,
因为在大多数jvm中,count–-的操作分为如下三步:
取得原有count值
计算 -1 的结果
进行赋值
并发线程获取count的值显然是无法避免脏数据 */ //使用锁 synchronized,即可解决线程脏数据
class MyThread3 extends Thread {
//公共数据
private int count = 5;
//每次new MyThread3只会执行一次run();
//添加了同步锁 synchronized
@Override
public synchronized void run() {
super.run();
int yu = count--;
System.out.println("由 线程 " + MyThread3.currentThread().getName() + " 计算,剩余count=" + yu); }
}
/*
由 线程 1 计算,剩余count=5
由 线程 5 计算,剩余count=4
由 线程 4 计算,剩余count=3
由 线程 3 计算,剩余count=2
由 线程 2 计算,剩余count=1
*/
5.使用 interrupt() 和 return 配合 停止线程

package com.example.javabaisc.myThread; import org.junit.jupiter.api.Test; /**
* 使用 interrupt() 和 return 配合 停止线程
*/ public class T4 { @Test
public void t() throws InterruptedException {
MyThread4 m = new MyThread4();
m.start();
//主线程休眠0.01秒后执行
Thread.sleep(10);
m.interrupt();
Thread.sleep(1000);
System.out.println("停了么?"); } } class MyThread4 extends Thread { //每次new MyThread4只会执行一次run();
@Override
public void run() {
super.run();
int i = 0;
while (true) {
//判断该线程是否被执行了interrupt()
if (this.isInterrupted()) {
System.out.println("线程被停止");
return;
}
System.out.println(i++);
} }
}
打印结果:

6.线程优先级对比
setPriority不一定起作用的,在不同的操作系统不同的jvm上,效果也可能不同
数字越大优先级越高,但不是优先级低就一定在优先级高的线程后面运行,而是运行的机率会低一些,,反之亦然。

package com.example.javabaisc.myThread; import org.junit.jupiter.api.Test; /**
* 线程优先级对比
* setPriority不一定起作用的,在不同的操作系统不同的jvm上,效果也可能不同
* 数字越大优先级越高,但不是优先级低就一定在优先级高的线程后面运行,而是运行的机率会低一些,,反之亦然。
*
*/
public class T5 {
@Test
public void t() {
MyThread5 a = new MyThread5("A");
MyThread5 b = new MyThread5("B");
// a.setPriority(10);
// b.setPriority(1);
a.setPriority(1);
b.setPriority(10);
a.start();
b.start(); } } class MyThread5 extends Thread { MyThread5(String name) {
super();
this.setName(name);
} @Override
public void run() {
super.run();
System.out.println("我是线程:" + Thread.currentThread().getName());
}
}
7.守护线程 ,当 用户线程 结束后,守护线程跟着结束
注意:
不可使用@Test测试 ,否则所有线程都会随着用户线程结束而结束,看不到非守护线程运行效果

package com.example.javabaisc.myThread; import org.junit.jupiter.api.Test; /**
* 守护线程 ,当 用户线程 结束后,守护线程跟着结束
*
* 不可使用@Test测试 ,否则所有线程都会随着用户线程结束而结束,看不到非守护线程运行效果
*
*
*/
public class T6 { public static void main(String[] args) throws InterruptedException {
MyThread6 a = new MyThread6();
//设置该线程为守护线程
a.setDaemon(true);
a.start();
Thread.sleep(1000);
System.out.println("用户线程结束,退出,守护线程也跟着退出"); }
} class MyThread6 extends Thread {
private int i = 0; @Override
public void run() {
while (true) {
System.out.println(i++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} } }
}
不设为守护线程的打印结果

设为守护线程的打印结果

java 线程 总结的更多相关文章
- Java线程并发:知识点
Java线程并发:知识点 发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备 ...
- Java线程的概念
1. 计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- 细说进程五种状态的生老病死——双胞胎兄弟Java线程
java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...
- 【转载】 Java线程面试题 Top 50
Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...
- 第24章 java线程(3)-线程的生命周期
java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- 第22章 java线程(2)-线程同步
java线程(2)-线程同步 本节主要是在前面吃苹果的基础上发现问题,然后提出三种解决方式 1.线程不安全问题 什么叫线程不安全呢 即当多线程并发访问同一个资源对象的时候,可能出现不安全的问题 对于前 ...
- 第21章 java线程(1)-线程初步
java线程(1)-线程初步 1.并行和并发 并行和并发是即相似又有区别: 并行:指两个或者多个事件在同一时刻点发生. 并发:指两个或多个事件在同一时间段内发生 在操作系统中,并发性是指在一段事件内宏 ...
- [转]Java线程安全总结
最近想将java基础的一些东西都整理整理,写下来,这是对知识的总结,也是一种乐趣.已经拟好了提纲,大概分为这几个主题: java线程安全,java垃圾收集,java并发包详细介绍,java profi ...
随机推荐
- 捷码:重塑DevOps,打造更流畅紧密的开发与服务交付业务链
捷码Gemcoder 1周前如果有机会安排一场行业吐槽大会,熟悉软件开发.交付.服务业务各环节的业内人士,对开发中的各种扯皮.交付反反复复.运维服务中的提心吊胆,往往会有很多深刻的体验和刻骨铭心的案例 ...
- centos部署代码仓库gitlab
目录 一.简介 二.程序部署 部署gitlab 汉化gitlab 三.设置管理员密码 网页方式 指令方式 一.简介 GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托 ...
- MySQL数据库如何查看数据文件的存放位置
SHOW GLOBAL VARIABLES;
- 如何基于 Docker 快速搭建 Springboot + Mysql + Redis 项目
目录 前言 项目目录 搭建项目 1. docker安装启动mysql以及redis 1.1 安装mysql 1.2 安装redis 2. 初始化数据库 3.创建项目 4.初始化代码 4.1 全局配置文 ...
- [BUUCTF]REVERSE——[FlareOn4]IgniteMe
[FlareOn4]IgniteMe 附件 步骤: 例行检查,32位程序,无壳 32位ida载入 当满足第10行的if条件时,输出G00d j0b!提示我们成功,看一下sub_401050函数 3.s ...
- M语言的写、改、删(Power Query 之 M 语言)
M语言基本上和其他语言一样,用敲键盘的方式写入.修改.删除,这个是废话. M语言可以在[编辑栏]或[高级编辑器]里直接写入.修改.删除,这个也是废话. M语言还有个地方可以写入.修改.删除,就是[自定 ...
- AtCoder Beginner Contest 173 题解
AtCoder Beginner Contest 173 题解 目录 AtCoder Beginner Contest 173 题解 A - Payment B - Judge Status Summ ...
- Go 的 golang.org/x/ 系列包和标准库包有什么区别?
在开发过程中可能会遇到这样的情况,有一些包是引入自不同地方的,比如: golang.org/x/net/html 和 net/html, golang.org/x/crypto 和 crypto. 那 ...
- JAVA读取本地html文件里的html文本
/** * 读取本地html文件里的html代码 * @param file File file=new File("文件的绝对路径") * @return */ public s ...
- centos使用docker 安装 rabbitMq 消息队列
1.拉取镜像 docker pull rabbitmq:3-management 如果出现报错: Get https://registry-1.docker.io/v2/: net/http: req ...