多线程

本文深入讲解了多线程的基本概念,包括进程与线程的区别、创建线程的两种方法(继承Thread类和实现Runnable接口)、线程的生命周期、调度机制、优先级设置等。此外还探讨了线程间的交互如休眠、让步、插队等行为,并介绍了如何通过同步机制解决多线程并发访问共享资源的安全问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多线程

进程和线程的概念

进程:正在进行中的程序。
线程:进程中一个负责程序执行的控制单元(执行路径),一个进程中可以多执行路径,称之为多线程。

创建线程的两种方式

继承Thread类

创建线程方式一:继承Thread类
步骤:
1,定义一个类继承Thread类。
2,覆盖Thread类中的run方法。
3,直接创建Thread的子类对象创建线程。
4,调用start方法开启线程并调用线程的任务run方法执行。

class MyThread extends Thread{
    public void run(){
        System.out.println("多线程开启");//需要多线程的执行的内容
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        Thread myThread1 = new MyThread();//创建线程并覆盖run()方法
        Thread myThread2 = new MyThread();
        myThread1.start();
        myThread2.start();
    }
}

实现Runnable接口

创建线程方式二:实现Runnable接口
步骤:
1,定义类实现Runnable接口。
2,覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3,通过Thread类创建线程对象,并将实现Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。
4,调用线程对象的start方法开启线程。

class MyRunThread implements Runnable{
    public void run() {
        System.out.println("多线程开启");//需要多线程的执行的内容
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        MyRunThread runThread = new MyRunThread();
        Thread myThread1 = new Thread(runThread);//创造线程并把MyRunThread类对象作构造函数的参数
        Thread myThread2 = new Thread(runThread);
        myThread1.start();
        myThread2.start();
    }
}

线程的生命周期(状态)

线程的调度

Java虚拟机会按照特定的机制为程序中的每个线程分配CPU的使用权,这种机制被称作线程的调度。

线程的优先级

线程的优先级用1~10之间的整数来表示,数字越大优先级越高。可以通过Thread类的setPriority(int newPriority)方法对其进行设置。

线程休眠(sleep(long millis))

线程休眠也就是让当前线程进入阻塞状态将UPU让给其他线程,通过Thread类的静态方法sleep(long millis)实现,注意此方法会声明抛出InterruptedException异常。(可实现线程的交替执行)

线程让步(yield())

线程让步也是让正在运行的线程暂停,但和线程休眠不同的是它是让线程进入就绪状态而非阻塞状态,通过Thread类的静态方法yield()实现。

线程插队(join())

当某个线程调用join()方法时,当前线程将被“插队”,需等待调用join()方法的线程执行完毕之后再继续运行。join() 方法有带参数和无参数。

线程唤醒

多线程同步(安全问题|synchronized)

当多个线程去访问同一个资源时,可能会引发一些安全问题。
解决办法:同步。让某个资源在一个时刻只能被一个线程访问。(加锁)

同步代码块

格式:

synchronized(锁对象lock) {   
需要同步操作共享资源的内容;   
} 

同步方法

格式:

synchronized 返回值类型 方法名 ([参数1,···]){}

同步方法和同步代码块的区别:

  • 同步方法的锁是固定的this。
  • 同步代码块的锁是任意的对象。
  • 建议使用同步代码块。

死锁

线程在执行同步代码时,不仅每次都要判断锁的状态,消耗资源效率低,而且还可以存在两个线程都在等待对方的锁,造成程序的停滞,这种现象称为死锁。(核心理解:相互等待)

class DeadLockThread implements Runnable{
    static Object lock1 = new Object();//lock1锁对象
    static Object lock2 = new Object();//lock2锁对象
    boolean flag;
    public void run() {
        if(flag==true){
            while(true){
                synchronized(lock1){//lock1锁对象上的同步代码块
                    System.out.println(Thread.currentThread().getName());
                    synchronized(lock2){//lock2锁对象上的同步代码块
                        System.out.println("此地不到达");
                    }
                }
            }
        }else{
            while(true){
                synchronized(lock2){
                    System.out.println(Thread.currentThread().getName());
                    synchronized(lock1){
                        System.out.println("此地不到达");
                    }
                }
            }
        }
    }
}

public class DeadLock {
    public static void main(String[] args) {
        DeadLockThread d1 = new DeadLockThread();
        DeadLockThread d2 = new DeadLockThread();
        d1.flag = true;
        d2.flag = false;
        new Thread(d1,"d1").start();//创建并开启线程d1
        new Thread(d2,"d2").start();//创建并开启线程d2
    }
}

输出:
d1
d2

原因:d1线程在拿到lock1后需得到lock2,但此时lock2在d2线程上,而d2线程又需要lock1,lock1又在d1上,所有形成了死锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值