成品网站代理,建设工程材料网站,大兴企业官网网站建设咨询,部队网站建设总结哈喽~大家好呀#xff0c;这篇来看看JAVA进程和线程。 #x1f947;个人主页#xff1a;个人主页 #x1f948; 系列专栏#xff1a;【日常学习上的分享】 #x1f949;与这篇相关的文章#xff1a; Redis快速入… 哈喽~大家好呀这篇来看看JAVA进程和线程。 个人主页个人主页 系列专栏【日常学习上的分享】 与这篇相关的文章 Redis快速入门及在Java中使用RedisRedis快速入门及在Java中使用Redis_程序猿追的博客-CSDN博客为什么不推荐使用LombokData不香吗为什么不推荐使用LombokData不香吗-CSDN博客Mybatis报错: Parameter ‘XXX‘ not found. Available parameters are [arg1, arg0, param1, param2]解决方案及问题原因Mybatis报错: Parameter ‘XXX‘ not found. Available parameters are [arg1, arg0, param1, param2]解决方案及问题原因-CSDN博客 目录
一、前言
1、进程和线程概念
2、线程的优先级
二、Thread 类
三、Runnable 接口
四、线程同步
1、synchronized 2、使用方式
五、死锁问题
六、生产者与消费者实战案例
七、图书推荐 一、前言
1、进程和线程概念
什么是进程 进程就是正在运行的程序它是系统资源调度的独立单位并且一个进程可以执行多个任务而线程就是程序执行的任务它是程序使用CPU的基本单位因此也可以说线程是依赖于进程的。像比如任务管理器里面的运行任务就是线程。
单进程与多进程的概述 单进程的计算机一次只能做一件事情而多进程的计算机可以做到一次做不同的事情比如一边听音乐一边听打游戏这两件事情虽然感觉起来是在同时一起进行的但其实是CPU在做着程序间的高效切换这才让我们觉得是同时进行的。
什么是线程
线程是程序执行中一个单一的顺序控制流程是程序执行流的最小单元是处理器调度和分派的基本单位。
一个进程可以有一个或多个线程各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。
线程的状态 线程的生命周期 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。 就绪状态: 当线程对象调用了start()方法之后该线程就进入就绪状态。就绪状态的线程处于就绪队列中要等待JVM里线程调度器的调度。 运行状态: 如果就绪状态的线程获取 CPU 资源就可以执行 run()此时线程便处于运行状态。处于运行状态的线程最为复杂它可以变为阻塞状态、就绪状态和死亡状态。 阻塞状态: 如果一个线程执行了sleep睡眠、suspend挂起等方法失去所占用资源之后该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种 等待阻塞运行状态中的线程执行 wait() 方法使线程进入到等待阻塞状态。 同步阻塞线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。 其他阻塞通过调用线程的 sleep() 或 join() 发出了 I/O 请求时线程就会进入到阻塞状态。当sleep() 状态超时join() 等待线程终止或超时或者 I/O 处理完毕线程重新转入就绪状态。 死亡状态: 一个运行状态的线程完成任务或者其他终止条件发生时该线程就切换到终止状态。
2、线程的优先级
每一个 Java 线程都有一个优先级这样有助于操作系统确定线程的调度顺序。
Java 线程的优先级是一个整数其取值范围是 1 Thread.MIN_PRIORITY - 10 Thread.MAX_PRIORITY 。
默认情况下每一个线程都会分配一个优先级 NORM_PRIORITY5。 二、Thread 类
使用 Thread 来创建线程类继承与 Thread 类。继承类必须重写 run() 方法该方法是新线程的入口点。它也必须调用 start() 方法才能执行。
格式
package com.zte.thread;public class ThreadA extends Thread{// run() 方法线程执行的第一步同main方法Overridepublic void run() {}}示例 public class ThreadA extends Thread{// run() 方法线程执行的第一步同main方法Overridepublic void run() {for (int i 1; i 200; i) {System.out.println(i : i);}}}public class ThreadB extends Thread{Overridepublic void run() {for (int i 0; i 200; i) {System.out.println(j : i);}}
}public class Text {public static void main(String[] args){ThreadA a new ThreadA();ThreadB b new ThreadB();a.start();b.start();}
}运行结果 打印太多了我们只看关键的一部分很明显多个线程明显在抢占资源
扩
这里我们看下 start() 与 run() 的区别
start() :
它的作用是启动一个新线程。 通过start()方法来启动的新线程处于就绪可运行状态并没有运行一旦得到cpu时间片就开始执行相应线程的run()方法这里方法run()称为线程体它包含了要执行的这个线程的内容run方法运行结束此线程随即终止。start()不能被重复调用。用start方法来启动线程真正实现了多线程运行即无需等待某个线程的run方法体代码执行完毕就直接继续执行下面的代码。这里无需等待run方法执行完毕即可继续执行下面的代码即进行了线程切换。
run() :
run()就和普通的成员方法一样可以被重复调用。 如果直接调用run方法并不会启动新线程程序中依然只有主线程这一个线程其程序执行路径还是只有一条还是要顺序执行还是要等待run方法体执行完毕后才可继续执行下面的代码这样就没有达到多线程的目的。 总结调用start方法方可启动线程而run方法只是thread的一个普通方法调用还是在主线程里
简单来说就是 start() 可以创建多个线程不能重复调用而 run() 创建单个线程能重复调用。 三、Runnable 接口
创建一个线程最简单的方法是创建一个实现 Runnable 接口的类使用 run 来调用线程
示例
public class ThreadA implements Runnable{// run() 方法线程执行的第一步同main方法Overridepublic void run() {for (int i 1; i 200; i) {try {Thread.sleep(1000); // 让线程睡眠一会} catch (InterruptedException e) {e.printStackTrace();}System.out.println(i : i);}}}public class ThreadB implements Runnable{Overridepublic void run() {for (int i 0; i 200; i) {try {Thread.sleep(1000); // 让线程睡眠一会} catch (InterruptedException e) {e.printStackTrace();}System.out.println(j : i);}}
}public class Text {public static void main(String[] args){ThreadA a new ThreadA();ThreadB b new ThreadB();a.run();b.run();}
}
扩
1、当我们使用了 Runnable 实例化对象就不能调用 start 方法了只能用 run 了。
2、sleep 的意思是强制当前正在执行的线程休眠暂停执行例如【Thread.sleep(long millis)】当线程睡眠时它不会在苏醒之前返回到可运行状态当睡眠时间到期后才会返回到可运行状态。里面放的毫秒值。 四、线程同步
1、synchronized
什么是 synchronized
答synchornized 是 Java 中的一个关键字解决的是多个线程之间访问资源的同步性synchronized 关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。
在上面我们遇到了线程抢占的问题而 synchronized 就是来解决这问题的。
应用场景 2、使用方式
修饰实例方法作用于当前对象实例加锁进入同步代码前要获得 当前对象实例的锁
synchronized void method() {//业务代码
}修饰静态方法: 也就是给当前类加锁会作用于类的所有对象实例 进入同步代码前要获得 当前 class 的锁。
synchronized static void method() {//业务代码
}修饰代码块 指定加锁对象对给定对象/类加锁。synchronized(this|object) 表示进入同步代码库前要获得给定对象的锁。synchronized(类.class) 表示进入同步代码前要获得 当前 class 的锁
synchronized(this) {//业务代码
}案例银行存钱与取钱
分析银行比作容器取钱与存放是两个进程并且不能同时进行。
public class Account extends Thread{private int balance 1000;Object o new Object(); // 或者用 thispublic void withdraw(int n){synchronized (o){balance - n;System.out.println(取了 : n 还剩 : balance);}}public void deptdraw(int n){synchronized (o){balance n;System.out.println(存了 : n 还剩 : balance);}}}public class PersonA extends Thread{private Account account;public Account getAccount() {return account;}public void setAccount(Account account) {this.account account;}Overridepublic void run() {for (int i 0; i 3; i) {account.withdraw(100);}}}public class PersonB extends Thread{private Account account;public Account getAccount() {return account;}public void setAccount(Account account) {this.account account;}Overridepublic void run() {for (int i 0; i 3; i) {account.deptdraw(100);}}}public class Text {public static void main(String[] args){Account acc new Account();PersonA a new PersonA();PersonB b new PersonB();a.setAccount(acc);b.setAccount(acc);b.start();a.start();}
}
运行结果 五、死锁问题
什么是死锁
答线程死锁是指由于两个或者多个线程互相持有对方所需要的资源导致这些线程处于等待状态无法前往执行。当线程进入对象的synchronized代码块时便占有了资源直到它退出该代码块或者调用wait方法才释放资源在此期间其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时会互相等待对方释放资源如果线程都不主动释放所占有的资源将产生死锁。
简单来讲就是t1 线程在等 t2 线程t2 线程也在等 t1 线程这就陷入到了死循环了这就叫死锁。
示例
public class AddAndSub {public Object objectA new Object();public Object objectB new Object();public void add(){synchronized (objectA){System.out.println(Thread.currentThread().getName() 我获取到了a);try {objectA.wait();System.out.println(我等到了);} catch (InterruptedException e) {e.printStackTrace();}synchronized (objectB){System.out.println(Thread.currentThread().getName() 我获取到了b);}System.out.println(Thread.currentThread().getName() 我失去了b);}System.out.println(Thread.currentThread().getName() 我失去了a);}public void sub(){synchronized (objectB){System.out.println(Thread.currentThread().getName() 我获取到了b);try {Thread.sleep(1000);
// System.out.println(我等到了);} catch (InterruptedException e) {e.printStackTrace();}// synchronized (objectB){System.out.println(Thread.currentThread().getName() 我获取到了a);
// objectA.notify();
// }System.out.println(Thread.currentThread().getName() 我失去了a);}System.out.println(Thread.currentThread().getName() 我失去了b);}}public class TB extends Thread{public AddAndSub addAndSub;Overridepublic void run() {addAndSub.sub();}
}public class TA extends Thread{public AddAndSub addAndSub;Overridepublic void run() {addAndSub.add();}
}public class Text {public static void main(String[] args){AddAndSub d new AddAndSub();TA a new TA();TB b new TB();a.setName(线程A);b.setName(线程B);a.addAndSub d;b.addAndSub d;a.start();b.start();a.setPriority(Thread.MAX_PRIORITY);}
}死锁了进程 A 一直在等进程 B 但 B 一直在等 A。 六、生产者与消费者实战案例
分析有一个箱子生产者生产牛奶放入到箱子里面消费者在箱子里面拿牛奶
示例
public class Box {private int milk 0;private boolean state false;public synchronized void put(int milk){if (state){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}this.milk milk;System.out.println(放了 this.milk 瓶奶);state true;notifyAll();}public synchronized void get(){if (!state){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}
// this.milk milk;System.out.println(拿走了 this.milk 瓶奶);state false;notifyAll();}}public class shengchan implements Runnable {private Box b;public shengchan(Box box) {this.b box;}Overridepublic void run() {for (int i 0; i 10; i) {b.put(i 1);}}}public class xiaofei implements Runnable {private Box b;public xiaofei(Box box) {this.b box;}Overridepublic void run() {while (true) {b.get();}}
}public class Main {public static void main(String[] args) {Box box new Box();shengchan shengchan new shengchan(box);xiaofei xiaofei new xiaofei(box);Thread threadA new Thread(shengchan);Thread threadB new Thread(xiaofei);threadA.start();threadB.start();}}运行结果 七、图书推荐
内容简介
本书从 MATLAB 基础语法讲起介绍了基于 MATLAB 函数的科学计算问题求解方法实现了大量科学计算算法。
本书分为三大部分。第 1 章和第 2 章为 MATLAB 的基础知识对全书用到的 MATLAB 基础进行了简单介绍。第 3 ~ 12 章为本书的核心部分包括线性方程组求解、非线性方程求解、数值优化、数据插值、数据拟合与回归分析、数值积分、常微分方程求解、偏微分方程求解、概率统计计算及图像处理与信号处理等内容。第 13 ~ 15 章为实战部分以实际生活中的数学问题为例将前文介绍的各类科学计算算法应用其中。
本书内容全面、通俗易懂适合有一定 MATLAB 基础、想要进行进阶学习的读者。 购买链接