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 ...
随机推荐
- java中关于string类和常量池的一点猜想
public class StringTest { /** * @param args */ public static void main(String[] args) { test1 ...
- 漏洞扫描器-AWVS
目录 介绍 漏洞扫描 网络爬虫==漏洞分析.验证 主机发现 子域名探测 SQL注入 HTTP头编辑 HTTP监听 介绍 AWVS为Acunetix Web Vulnarability Scanner的 ...
- 6、Redis五大数据类型---列表(List)
一.列表(List)简介 单键多值:Redis 列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素到列表的头部(左边)或者尾部(右边). 它的底层实际是个双向链表,对两端的操作性能很高,通过 ...
- java多线程5:线程间的通信
在多线程系统中,彼此之间的通信协作非常重要,下面来聊聊线程间通信的几种方式. wait/notify 想像一个场景,A.B两个线程操作一个共享List对象,A对List进行add操作,B线程等待Lis ...
- 阿里云RDS备份 恢复到本地
目录 一.恢复准备 二.具体操作 一.恢复准备 阿里云RDS默认配置了全备份+binlog,可以精准恢复到某个时间点上. 可以下载备份的包到本地,进行本地恢复,要预留好本地的数据库容量和cpu等规格, ...
- MySQL如何使用WITH ROLLUP函数
一.WITH ROLLUP函数适用于跟在GROUP BY 字段后面进行分组求和使用 SELECT t1.`产品名称`,SUM(t1.`数量`),SUM(t1.`金额`),t1.`日期` FROM sh ...
- 子组件dispatch导致其他页面刷新问题解决
问题: 现在有一个页面,包含"项目基本要素"和"供应链管控要素"多个组件,其中一个组件有表单级联,通过产品类型的不同选取去调接口获得产品名称的下拉 调接口是通过 ...
- 如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1
原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...
- Vs code配置Go语言环境-Mac
背景:最近受朋友介绍,学习Go语言.那么开始吧,首先从配置环境开始. 电脑:Mac Air,Vs code已经安装 一.Go下载和安装 下载地址:https://golang.google.cn/dl ...
- Jquery监控audio单选框选中事件(实际通过click)
$('input:radio[name="pathType"]').click(function(){ var checkValue = $('input:radio[name=& ...