简介:详解Java多线程相关知识。
程序是为了完成特定任务,用某种语言编写的一组指令的集合,即指一段静态代码块
,静态对象。
进程是程序的一次执行过程,或者是正在执行的一个程序
,是一个动态的过程。有它自生 产生,存在,消亡的过程。
进程作为资源分配的单位,每个进程启动时系统都会为他分配不同的内存区域。
独立的运行栈和
程序计数器
(PC寄存器)单车道
多车道
/**
* @author: 【写Bug的小杜 <email@shaoxiongdu.cn>
* @date: 2021/07/20
* @description: 写一个遍历100以内偶数的线程
*/
class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println( Thread.currentThread().getName() + " --- > i = " + i);
}
}
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
MyThread myThread1 = new MyThread();
myThread1.start();
}
currentThread
返回当前线程set/getName
设置获取当前线程名字static sleep(long time)
: 阻塞当前线程,但不释放锁static yield
回到就绪状态,释放锁,接下来也可能会再次抢到执行权。join
实例方法,将当前线程阻塞,等实例结束之后,在执行。
isAlive
: 判断是否存活get/setPriority
: 获取/设置优先级 /**
* 最低
*/
public final static int MIN_PRIORITY = 1;
/**
* 默认
*/
public final static int NORM_PRIORITY = 5;
/**
*最高
*/
public final static int MAX_PRIORITY = 10;
当某个线程在操作共享数据的时候,尚未完成操作,其他线程进入操作数据,就会产生线程安全问题。
当一个线程操作共享数据的时候,其他线程不能参与进来,直到当前线程结束。
通过同步机制,解决线程安全问题。
//保证同步监视器必须是多线程共享的对象
synchronized(同步监视器){
//操作共享数据的代码
}
public synchronized void setBlance(){
//
}
锁为this
。锁为类
。JDK5.0新增
class Window3 implements Runnable{
private int ticket = 100;
//实例化一个锁
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (ticket > 0){
try {
//加锁
lock.lock();
if(ticket > 0){
System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);
ticket--;
}
} finally {
//释放锁
lock.unlock();
}
}
}
}
同
都可以解决线程安全问题
异
//单例
class Bank{
//构造私有 防止外部创建对象
private Bank(){}
private static Bank instance = null;
//懒汉式 用到时在创建
public static Bank getInstance(){
if(instance == null){
synchronized (Bank.class) {
if(instance == null){
instance = new Bank();
}
}
}
return instance;
}
}
不同的线程分别占用对方的锁不放弃,都在等待对方放弃自己需要的锁,形成线程的死锁。
```java
Object o1 = new Object();
Object o2 = new Object();
new Thread( ()-> {
//先锁o1
synchronized (o1){
System.out.println(Thread.currentThread().getName() + "锁住了o1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "等待锁o2");
synchronized (o2){
}
}
} ).start();
new Thread( ()-> {
//先锁o2
synchronized (o2){
System.out.println(Thread.currentThread().getName() + "锁住了o2");
// 锁o1
System.out.println(Thread.currentThread().getName() + "等待锁o1");
synchronized (o1){
}
}
} ).start();
```
造成了死锁现象。程序无法正常结束,也不会报异常。
![image-20210721154559637](https://gitee.com/ShaoxiongDu/imageBed/raw/master//images/image-20210721154559637.png)
wait
当前线程进入阻塞状态,释放锁notify
唤醒被wait的线程,如果有多个,唤醒优先级最高的notifyAll
: 唤醒全部被wait的线程call可以有泛型返回值
可以抛出异常
需要借助FutureTask类,比如获取返回结果
// 创建一个实现Callable的实现类
class MyCallable implements Callable{
//实现call方法
@Override
public Object call() throws Exception {
System.out.println(Thread.currentThread().getName() + "is run !");
return null;
}
}
public static void main(String[] args) {
//创建Callable接口实现类的对象
Callable c = new MyCallable();
//将此接口实现类的对象传入到FutureTask中
FutureTask futureTask = new FutureTask<>(c);
new Thread(futureTask).start();
//futureTask的get方法可以获取call的返回值
}
好处
static class Something implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " : some is run!");
}
}
public static void main(String[] args) {
//通过Executors工具类返回一个可以重复使用的指定数量的线程池
//ExecutorService是一个接口
ExecutorService service = Executors.newFixedThreadPool(100);
//调用execute方法 传递Runable接口的实现类 自动start
service.execute(new Something());
//通过getClass 可以知道实际创建的是ThreadPoolExecutor的对象 ThreadPoolExecutor实现了ExecutorService接口
System.out.println(service.getClass()); //ThreadPoolExecutor
//将其强转为ThreadPoolExecutor
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) service;
int corePoolSize = threadPoolExecutor.getCorePoolSize();
System.out.println("corePoolSize = " + corePoolSize);
//关闭连接池
service.shutdown();
}