多线程概述(1)

本文介绍了多线程的运行原理,包括进程和线程的概念,以及多线程如何在操作系统中并发执行。接着详细讲解了Java中创建线程的两种方式:继承Thread类和实现Runnable接口,包括每种方式的步骤、示例和优缺点。最后通过售票的例子展示了多线程在实际应用中的场景。

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

多线程概述(1)

1.多线程的运行原理

(1)多线程概述

提到线程就要提出进程的概念,进程可以说是正在运行的程序,或者更确切的说是当一个程序开始运行的时候,就变成了一个进程,进程是系统进行资源分配和调度的一个单位。

而线程就是进程中的一个执行单元,负责当前进程中程序的执行。一个程序运行后至少有一个进程,一个进程中至少会有一个线程,另外一个进程中可以有多个线程,这样的程序就是多线程程序。

(2)多线程的运行原理

大多数操作系统都支持多进程并发运行,现在的操作系统几乎都支持同时运行多个任务,其实这些软件在某一时刻,只会运行一个进程。由于cpu在高速切换而导致的。对于CPU而言,它在某个时间点上,只能执行一个程序,CPU不断地在这些进程中切换。由于CPU执行速度对我们而言速度很快,所以在我们看来就是多个进程同时执行。

2.线程的创建

(1)主线程

在程序运行中一定会有一个执行线程从main方法开始的。一直执行到main方法结束。这个线程在java中称之为主线程。当主线程在这个程序中执行时,如果遇到了循环而导致程序在指定位置停留时间过长,无法执行下面的程序,而多线程就可以解决这个问题,一个主线程负责执行其中一个循环,由另一个线程负责其他代码的执行。

(2)继承Thread类创建线程

步骤
  • 定义一个类继承Thread;
  • 重写run()方法;
  • 创建子类对象,就是创建线程对象;
  • 调用start方法,开启线程并让线程开始执行,同时系统层面告诉jvm去调用run方法。
举例
class Demo extends Thread{//继承了Thread类
    String name;
    Demo(String name){
        this.name = name;
    }
    public void run(){
        for (int i = 1;i<=20;i++){
            System.out.println(name+"i="+i);
        }
    }
}

public class Demo01{
        public static void main(String[] args) {
        Demo d1 = new Demo("小徐");
        Demo d2 = new Demo("小张");
        d1.run();//仅仅只是主线程调用了run方法,并没有开启新的线程
        d1.start();//开启一个线程
        d2.start();
        }
    }

在上述代码中如果仅仅调用run方法,并不会开启线程,只是主线程在main里调用了run方法而已。

创建线程的目的

建立了单独的执行路径,让多部分代码实现同时执行。自定义线程需要执行的任务都定义在run方法里,但是Thread类中本身的run方法又不一定是我们需要的,而Thread类已经定义了线程任务的位置,只要定义位置中定义任务代码就可以了,然后重写run方法。

(3)实现Runnable接口创建线程

步骤
  • 定义类实现Runnable接口;
  • 覆盖接口中的run方法;
  • 创建Thread类的对象;
  • 将Runnable接口的子类对象作为参数传递给Thread类的构造函数;
  • 调用Thread类的start方法开启线程;
举例
class Demo implements Runnable{
    String name;
    Demo(String name){
        this.name = name;
    }
    public void run(){
        for (int i = 1;i<=20;i++){
            System.out.println(name+"..."+Thread.currentThread().getName()+"..."+i);
        }
    }
}

public class Demo01{
        public static void main(String[] args) {
        Demo d = new Demo("小徐");//此处不是线程对象,只是创建了Runnable子类的对象
        //创建Thread类的对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数
        Thread t1 = new Thread(d);
        Thread t2 = new Thread(d);
        t1.start();//线程启动
        t2.start();
        }
    }

与继承Thread类创建的线程的区别

实现Runnable接口,避免了继承Thread类的单继承局限性。覆盖Runnable接口中的run方法,将线程任务代码实现到run方法中,创建Thread类的对象,只有创建Thread类的对象才可以创建线程。

实现Runnable接口的好处

线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建了Thread类的子类对象,即使线程对象,又是线程任务。实现Runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。

3.关于多线程的应用(售票)

对于这种多线程同步进行,且共享同一对象(票),可以用实现Runnable接口的方式创建多线程。

class Demo implements Runnable{
    private int tickets = 100;
    public void run(){
        while (true){
            if (tickets>0){
                System.out.println(Thread.currentThread().getName()+"正在发售第"+tickets--+"张票");

            }
        }
    }
}

public class Demo01{
        public static void main(String[] args) {
        Demo d = new Demo();//创建实例对象
        Thread t1 = new Thread(d,"售票窗口1");
        Thread t2 = new Thread(d,"售票窗口2");
        Thread t3 = new Thread(d,"售票窗口3");
        Thread t4 = new Thread(d,"售票窗口4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值