Java高并发-多线程基础
一、什么是线程
线程是进程内的执行单元。
二、线程的基本操作
2.1 状态与操作

2.2 新建线程
Thread t1 = new Thread(new CreateThread());
t1.start();
# 直接覆盖run方法
# 传target实例,即Runnable接口实例

2.3 终止线程

2.4 中断线程
public void Thread.interrupt(); // 中断线程
public boolean Thread.isInterrupted(); // 判断是否被中断
public static boolean Thread.interrupted(); // 判断是否被中断,并清除当前中断状态
public static native void sleep(long millis) throws InterruptedException
代码
// 线程t1
public void run() {
while(true) {
Thread.yield();
}
}
// 对线程t1进行中断操作,线程t1并不会做出响应
t1.interrupt();
// 执行下面这段代码的线程,会对中断做出响应
public void run() {
while(true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted!");
break;
}
Thread.yield();
}
}
sleep代码
// 在等待的过程中,也对中断操作做出响应
public void run() {
while(true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println('Interrupted!');
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("Interrupted When Sleep");
// 设置中断状态,抛出异常后会清除中断标记位
Thread.currentThread().interrupt();
}
Thread.yield();
}
}
2.5 挂起和继续执行线程
suspend()不会释放锁
如果加锁发生在resume()之前,则发生死锁
这两个就法不推荐使用

模拟死锁:
public class BadSuspend {
public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
public static class ChangeObjectThread extends Thread {
public ChangeObjectThread(String name) {
super.setName(name);
}
@Override
public void run() {
synchronized(u) {
System.out.println("in " + getName());
Thread.currentThread().suspend();
}
}
}
public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(100);
t2.start();
t1.resume();
t2.resume();
t1.join();
t2.join();
}
}
分析:
t1线程正常结束,t2线程死锁


2.6 等待线程结束和谦让
join,yeild
// 把自己占用的CPU机会释放掉,再和别人一起竞争CPU
public static native void yield();
// 当前线程未做完,主线程等待当前线程做完后再往下走
public final void join() throws InterruptedException
public final synchronized void join(long millis) throws InterruptedException


三、守护线程
在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程
当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出

四、线程优先级
高优先级的线程更容易在竞争中获胜
t1.setPriority(Thread.MAX_PRIORITY);
五、基本的线程同步操作
5.1 synchronized
指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。
直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。
指定加锁对象
public class AccountingSync implements Runnable {
static AccountingSync instance = new AccountingSync();
static int i = 0;
@Override
public void run() {
for (int j=0;j<100000;j++) {
synchronized(instance) {
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}

作用于实例方法:注意多个线程要对同一个实例加锁
public class AccountingSync2 implements Runnable {
static AccountingSync2 instance = new AccountingSync2();
static int i = 0;
public synchronized void increase() {
i++;
}
@Override
public void run() {
for (int j=0;j<100000;j++) {
increase();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}

作用于静态方法:注意区别 作用于实例方法

5.2 wait()/notify()
notify()之后,允许线程往下走,但是如果没有获得锁的话,也还是执行不了,t2.notifyAll()之后t1就可以往下执行了,但是此时t1还未获得object锁,必须等t2睡2秒后,获得object锁后执行。


Java高并发-多线程基础的更多相关文章
- Java高并发编程基础三大利器之CountDownLatch
引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...
- java高并发编程基础之AQS
引言 曾经有一道比较比较经典的面试题"你能够说说java的并发包下面有哪些常见的类?"大多数人应该都可以说出 CountDownLatch.CyclicBarrier.Sempah ...
- Java高并发与多线程(二)-----线程的实现方式
今天,我们开始Java高并发与多线程的第二篇,线程的实现方式. 通常来讲,线程有三种基础实现方式,一种是继承Thread类,一种是实现Runnable接口,还有一种是实现Callable接口,当然,如 ...
- Java高并发与多线程(四)-----锁
今天,我们开始Java高并发与多线程的第四篇,锁. 之前的三篇,基本上都是在讲一些概念性和基础性的东西,东西有点零碎,但是像文科科目一样,记住就好了. 但是本篇是高并发里面真正的基石,需要大量的理解和 ...
- java高并发系列 - 第16天:JUC中等待多线程完成的工具类CountDownLatch,必备技能
这是java高并发系列第16篇文章. 本篇内容 介绍CountDownLatch及使用场景 提供几个示例介绍CountDownLatch的使用 手写一个并行处理任务的工具类 假如有这样一个需求,当我们 ...
- Java高并发与多线程(三)-----线程的基本属性和主要方法
今天,我们开始Java高并发与多线程的第三篇,线程的基本属性和主要方法. [属性] 编号(ID) 类型long 用于标识不同的线程,编号唯一,只存在java虚拟机的一次运行 名称(Name) 类型St ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- Java高并发如何解决
Java高并发如何解决 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就坦然面对吧 ...
- 转载:Java高并发,如何解决,什么方式解决
原文:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并 ...
随机推荐
- 联想电脑“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态” 解决方法
当在虚拟机上安装Ubuntu系统时,出现 "此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态" 弹窗此时需要进入BIOS修改相关的设置,此处以联想ideap ...
- Altium design16设计技巧
第一栏:共有界面 1.在原理图和PCB都打开的情况下,选中原理图可以对应到PCB界面元件里面 第二栏:原理图界面 1.批量改变元件属性 选择某一元件-查找相似对象-将其要改变的内容设置为same-点击 ...
- 洛谷 P5706 【深基2.例8】再分肥宅水
题目连接: P5706 [深基2.例8]再分肥宅水 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 我提交的: 1 #include<iostream> 2 #inclu ...
- eBPF Cilium实战(1) - 基于团队的网络隔离
在 Rainbond 集群中,每个团队对应于底层 Kubernetes 的一个 Namespace ,由于之前使用的底层网络无法进行 Namespace 级别的网络管理,所以在 Rainbond 同一 ...
- Java学习day13
泛型类格式: 修饰符 class 类名<类型>{ } 常用T.E.K.V等形式的参数表示泛型 使用方式与C++的类模板相似,在创建对象时要明确数据类型 泛型方法定义格式: 修饰符<类 ...
- 使用 mix-blend-mode 实现抖音 LOGO
<template> <div class="g-container"> <div class="j"></d ...
- Blazor 修改错误提示
我们在blazor中,如果代码有异常,会产生如下的错误 在群里很多朋友都问,这个错误提示是英文的,能不能改成中文? 这个当然是可以的. 其实这个错误描述是在项目里自己定义的,具体内容可以看_Layou ...
- Hyperledger Fabric 部署在多个主机上
前言 在实验Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务.TLS组织运行维护Orderer服务中,我们已经完成了使用提供 TLS-CA 服务的 council ...
- 共读《redis设计与实现》-单机(一)
上一章我们讲了 redis 基本类型的数据结构 和 对象系统 ,这篇来说一下单机redis 的知识点. 一.数据库 一个数据库在redis中就有一个结构体,而数据库的结构体是由redisServer这 ...
- 《图解UE4渲染体系》Part 0 引擎基础
在介绍UE4渲染体系前,我们有必要来先看一下UE4是用什么样的方式来构建游戏场景数据的. 1 Object 在UE4中当我们说Object,通常是指代引擎代码中的UObject类,它是引擎里管理绝大部 ...