Java多线程基础
相关概念
程序:指令的集合(代码)
进程:是程序的一次执行过程,包括产生、存在和消亡的过程
线程:是进程的一个实体,一个进程可以拥有多个线程。
单线程:同一时刻,只允许执行一个线程。
多线程:同一时刻,可以执行多个线程。
并发:同一时刻,多个任务交替执行,单核CPU(人脑)
并行:同一时刻,多个任务同时执行,多核CPU
创建线程的两种方式
继承Thread类,重写run方法
class Cat extends Thread {
@Override
public void run() {//重写run方法,写上自己的业务逻辑
while (true) {
//该线程每隔1秒在控制台输出“瞄瞄,我是小猫咪"”
system.out.println("瞄瞄,我是小猫咪");
//让该线程休眠1秒
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread01 {
public static void main(String[] args) {
//创建Cat对象,可以当做线程使用
Cat cat = new Cat();
cat.start();//启动线程,主线程不会阻塞,与子线程交替执行
}
}
为什么是调用start而不是run方法
调用start方法才是开辟子线程,直接调用run方法则是在主线程中顺序执行
实现Runnable接口,重写run方法(推荐)
因为Java是单继承的,某些情况下一个类可能已经继承了某个父类,所以可以通过实现Runnable接口
此外,该方式比较适用于多个线程共享资源的情况
public class Thread02 {
public static void main(String[] args) {
Dog dog = new Dog();
//dog.start();这里不能调用start
Thread thread1 = new Thread(dog);
thread1.start();
}
}
使用了设计模式——(静态)代理(Proxy)模式
多线程
不同线程完成不同的事
多线程售票:
出现了票数为负的情况
线程终止
1、自动退出
2、通知方式:通过使用变量来控制run方法退出
重写run方法的类中设置一个控制变量作为run方法中循环体的循环条件,并设置set方法,破坏循环条件退出run方法从而终止线程
线程状态
1、NEW新建状态
2、RUNNABLE可运行状态
3、BLOCKED阻塞
4、WAITTING等待
5、TIMED_WAITTING超时等待
6、TERMINATED终止
线程同步synchronized(加锁)
多线程编程中,内存中一些敏感数据不允许被多个线程同时访问,此时就使用同步技术,保证内存地址在同一时刻,最多被一个线程访问,以保证数据的完整性。
使用synchronized修饰方法,称为同步方法,run()中调用该同步方法。
1、同步方法如果没有使用static修饰:默认锁对象为this
2、如果方法使用static修饰,默认锁对象:当前类.class
或选择同步代码块(推荐)
@Override
public void run() {
while(true){
synchronized (this) {//object是锁
//同步代码
}
}
}
同步原理
互斥锁:每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
要求多个线程的锁对象为同一个。
释放锁:执行完毕释放
例题:
(1)在main方法中启动两个线程
(2)第1个线程循环随机打印100以内的整数
(3)直到第2个线程从键盘读取了“Q”命令。
class A extends Thread {
private boolean loop = true;
@Override
public void run() {
//输出1-100数字while (loop) {1
system.out.println((int)(Math .random() * 100 + 1));
//休眠
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}
}
class B extends Thread {
private A a;
private Scanner scanner = new Scanner(System.in);
public B(A a){//构造器中,直接传入A类对象
this.a = a;
}
@Override
public void run() {
while (true) {
//接收到用户的输入
System.out.println("请输入你指令(Q)表示退出: ");
char key = scanner.next().toUpperCase().charAt(0);
if(key == 'Q') {
//以通知的方式结束a线程
a.setLoop(false);
System.out.printLn("b线程退出");
break;
}
}
}
}
public class test01 {
public static void main(String[] args) {
A a = new A();
B b = new B(a);//一定要注意
a.start();
b.start();
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)