📖博主介绍
个人主页: Zinksl
编程社区: Zinksl编程酒馆
个人格言: 想法落实的最佳时机就是现在!🏄
如果你 喜欢交流或热爱分享,欢迎加入编程社区或交流群 大家一起学习技术,交流心得,共同进步🚅
使用Java的Thread类来创建和管理程。线程的生命周期包括五个状态:新建、就绪、运行、阻塞和死步与互斥: 当多个程共享同一资源时,性Java提供了synchronized关. 线程安全的概念和正确的执行,不会出现数据竞争和错误情况发生。Java提供类概锁造成的一种阻塞状态。方法来避免死锁的发生程的工具类: Java提供了一些并发编的工具类,比如Semaphore、CountDownLatch、CyclicBarrier等来实现程之间的协作和控制概是,当有任务需要处理时接从线程池中取出线程使用,可以优化线程创建和销毁过程,减7. 分析线程和并在开发过程中,我们需要使用一些工具和方法来分析和解决线程和发问题,比如线程 Dump、JVMTI、JConsole等
思维导图
1 线程的使用
1.1 创建线程
创建线程可以通过两种方式,①继承Thread类重写run方法;②实现Runnable接口,重写run方法
**两种方式的异同点:**①实现Runnable接口更适合资源共享,一个资源被多个线程调用(建议使用Runnable)
(1)继承Thread类,重写run方法
- 查看Thread类图【打开方式:选中类名右键,选择diagrams**】**
① 当一个类继承了Thread类,则该类就可以当线程使用
② 当一个类继承了Thread类,需要重写run方法
③ 开启线程方法和休眠方法
public class Cat extends Thread{
@Override
public void run() {
// 需求:每隔1秒输出一句话
// 让线程休眠1秒钟
int flag = 0;
while (flag <8){
try {
Thread.sleep(1000);
System.out.println("登峰造极!"+(flag+1)+" 线程名:"+Thread.currentThread().getName());
flag++;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static void main(String[] args) {
Cat cat = new Cat();
cat.start();//启动线程
// 执行主线程程其他逻辑
for (int i = 0; i < 6; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("我是主线程"+i+" 线程名:"+Thread.currentThread().getName());
}
}
(2)实现Runnable接口,重写run方法
① 当一个类实现了Runnable接口,则该类就可以当线程使用
② 需要重写run方法
③ 需要使用代理模式将实现了Runnable接口的类对象,传给Thread,通过Tread对象调用star方法启动线程
public class Dog implements Runnable{
public void run() {
// 需求:每隔1秒输出一句话
// 让线程休眠1秒钟
int flag = 0;
while (flag <8){
try {
Thread.sleep(1000);
System.out.println("登峰造极!"+(flag+1)+" 线程名:"+Thread.currentThread().getName());
flag++;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static void main(String[] args) {
// ① 通过继承Thread类,启动线程
Cat cat = new Cat();
cat.start();//启动线程
// ② 通过实现Runnable接口,启动线程
Dog dog = new Dog();
Thread thread = new Thread(dog);
thread.start();
// 执行主线程程其他逻辑
for (int i = 0; i < 6; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("我是主线程"+i+" 线程名:"+Thread.currentThread().getName());
}
}
1.2 多线程的同步和互斥
(1)线程终止
子线程中设置一个变量,通过变量控制run方法的运行,主线程中修改子线程的变量从而达到控制线程终止的效果;
(2)线程同步机制
在多线程编程中,一些敏感数据不允许被多个线程同时访问,此时就可以使用同步访问技术,保证数据在任何时间最多有一个线程访问;保证数据的完整性
①java语音中,引入了对象互斥锁的概念,来保证共享数据的操作的完整性
②每个对象都对应一个可称为"互斥锁"的标记,这个标记用来保证在任意时刻,只能有一个线程访问该对象
③关键字synchronized与对象互斥锁联系,当某个对象用synchronized修饰时,表明该对象在任意时刻只能由一个线程访问
④同步锁局限性:导致程序执行效率降低
⑤同步方法(非静态)的锁可以是this,也可以是其他对象要求是同一个对象
⑥同步方法(静态)的锁为当前本身
- 同步实现方法:Synchronized
- 同步代码块
synchronized(对象){
// 得到对象的锁才能操作,同步代码
// 需要同步的代码
}
- sycchronized还可以房租方法声明中,表示整个方法-为同步方法
public synchronized void method(){
// 需要同步的代码
}
(3)线程的死锁
(4)释放锁
-
释放锁的4种情况
:::warning
1 当线程的同步方法,同步代码块执行结束
2 当线程在同步代码块,同步方法中遇到break,return
3 当线程在同步代码块、同步方法中出现了为处理的Error或Exception导致异常结束
4 当线程在同步代码块、同步方法中执行了线程对象的wait方法,当前线程暂停比并释放锁
::: -
不会释放锁的情况
:::info
1 线程在调用同步代码块或者同步方法时,程序调用Thread.sleep(),Thread.yield()方法暂停当前线程执行,不会释放锁
2 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁
:::
1.3 线程常用的方法
方法名 | 说明 | 备注 |
---|---|---|
setName | 设置线程名称 | |
getName | 返回线程名称 | |
star | 该线程开始执行,java虚拟机底层调用该线程的star0方法 | |
run | 调用线程对象,run方法 | |
setPriority | 更改线程优先级 | |
getPriority | 获取线程优先级 | |
sleep | 指定毫秒数,让当前线程休眠 | |
interrupt | 中断线程 | |
yield | 线程的礼让,让出cpu,让其他线程执行,但时间不确定; | |
join | 线程插队,插队的线程一旦插队成功,则肯定先执行完插入的线程所有任务 |
1.4 用户线程和守护线程
用户线程:也叫工作线程
**守护线程:**一般是为工作线程服务的,当用户线程结束,守护线程自动结束;
常见的守护线程的机制:垃圾回收机制
(1)创建守护线程
Small small = new Small();
// 设置线程为守护线程
small.setDaemon(true);
1.5 线程的生命周期
结尾彩蛋
认真分享技术,记录学习点滴若内容对你有用可以鼓励一下🍻方式如下
点赞:👍 留言:✍收藏:⭐️
如有疑问欢迎评论区留言,或加入技术交流群:1002743802
关注我订阅专栏,会持续体系化更新哦👈