认识多线程

本文详细介绍了多线程的概念,强调了线程与进程的区别,包括资源管理和并发优势。讲解了如何通过继承Thread类、实现Runnable接口以及匿名内部类和Lambda表达式创建线程,并讨论了创建线程的不同方式和线程同步的重要性。
摘要由CSDN通过智能技术生成

认识线程

线程概念

首先多进程已经很好的实现了并发编程的效果,但是有一个很明显的缺点:进程太重(1.资源消耗更多2.速度更慢),如果需要大规模的创建和销毁进程,开销就会很大,具体体现在需要给进程分配资源,而线程就解决了不去分配内存硬盘资源问题,只需要分配一个简单的pcb.
在创建的时候,把资源分配好,后续创建的线程,让线程在进程内部(进程之间的关系,可以认为是进程包含了线程),后续在进程中的新线程中,直接复用前面进程创建的好的资源,其实一个进程,至少包含了一个线程存在,即主线程,最初创建的时候,可以认为是一个只包含了一个线程的进程(此时创建的时候需要资源分配,创建的开销会比较大),但是后续在这个进程里面创建线程,就可以省略分配资源的过程,这些线程在各自独立的cpu上进行调度.因此,线程就既可以完成"并发编程",又可以以比较轻量的方式来运行.

进程和线程的区别和联系

进程和线程的区别和联系

  1. 进程包含线程,都是为了实现并发编程的方式,线程比进程更轻量.
  2. 进程是系统分配资源的基本单位,
    线程是系统调度执行的基本单位
    创建进程的时候已经,操作系统会分配独立的资源(主要是虚拟地址空间和文件描述符表),后续创建线程的时候,直接共享进程的资源即可
  3. 每个进程都有自己独立的地址空间,不同进程之间无法直接访问彼此的内存空间,进程之间相对独立,一个进程的崩溃不会直接影响到其他线程.
    同一进程内的线程可以共享资源,通信和数据共享比较容易,线程的创建,销毁开销小,可以共享进程的上下文.但是由于线程共享一份地址空间,就需要注意线程间的同步和互斥,避免发生争端,一个线程的问题可能会影响整个进程的稳定性.

在这里插入图片描述

如何创建线程

多线程程序和普通程序的区别:

  1. 每一个线程都是一个独立的执行流.

  2. 多线程之间都是并发关系.

    1. 继承Thread类
      1 ) 继承Thread来创建一个线程类
class MyThread extends Thread {
     @Override
     public void run() {
        System.out.println("运行线程的的代码");
    }
}

2 )创建Mythread类的实例

MyThread t = new MyThread();

3 )调用start方法启动线程

t.start();//线程启动
class Mythread extends Thread{
    //对run方法重写,run相当于线程的入口,描述具体做什么事
    @Override
    public void run() {
        System.out.println("hello world");
    }
}
//写一个简单的hello world
public class demo1 {
    public static void main(String[] args) {
        Mythread mythread = new Mythread();
        //start就是在创建线程,会在底层调用操作系统的API,同时操作系统内核会创建出对应的pcb结构,这个创建出来的线程会参与到cpu的调度中,执行的工作是重写run方法
        mythread.start();
        //我们使用run方法,也会打印出hello world,但是并没有调用系统api,也没有创建出线程
        mythread.run();
    }
}
class Mythread extends Thread{
    @Override
    public void run() {
        while (true) {
            System.out.println("hello world");
        }
    }
}
public class demo1 {
    public static void main(String[] args) {
        Mythread mythread = new Mythread();
        //会创建一个新的线程执行run方法,主线程继续执行说明两个线程时并发执行,都能参与到cpu的调度中
        mythread.start(); //交替打印hello world和hello
        //只有一个线程,调用run方法时,必须把run执行完才能继续往下执行.
        mythread.run();//一直打印hello world

        while (true) {
            System.out.println("hello main");
        }
    }
}

当我们运行程序的时候,就会先创建一个Java进程,这个进程中就至少包含了一个线程,这个线程就叫做主线程也就是执行main方法的线程.

  1. 实现Runable接口
    1 )实现Runable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("这里是线程运行的代码");
    }
}

2 )创建Thread对象,把runnable作为参数传到Thread构造方法

Thread t = new Thread(new MyRunnable());

3 ) 调用 start 方法

t.start();//线程启动
class MyRunnable implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("hello thread");
            //这里只能try...catch不能throw
            //此处是方法重写,对于父类run方法来说,没有throw xxx异常这样的设定,因此再重写的时候,也就不能throw
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class demo2 {
   public static void main(String[] args) throws InterruptedException {
        MyRunnable runnable = new MyRunnable();
        //创建Thread对象,把runnable作为参数传到Thread构造方法
        Thread t = new Thread(runnable);
        t.start();
        while (true) {
            System.out.println("hello main");
            //主线程调用Thread.sleep方法时,会先暂停当前线程执行的任务,等待时间以毫秒为单位,
            //如果指定的时间超过了指定的时间间隔(这种情况为1秒),线程就会一直等待,直到时间到达为止
            Thread.sleep(1000);
        }
    }
}

对比上面两种方法:

  • Thread直接把要完成工作,放到了Thread的run方法中
  • Runnable则是分开操作,把要完成的工作放到Runnable中,再让Runnable和Thread配合,这就使得Runnable把线程要执行的任务和线程本身,进一步的解耦合了.

其他创建线程的方式

  • 匿名内部类创建Thread子类对象
public class demo1 {
    public static void main(String[] args) {
        //创建子类.子类继承自Thread,子类没有名字,并且类的创建实在demo1这个类里面
        //创建了子类实例,使用t这个引用来指向
        Thread t = new Thread() {
            @Override
            //在子类中重写run方法
            public void run() {
                while(true) {
                    System.out.println("hello");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
    }
}

  • 匿名内部类创建Runnable子类对象
public class demo2 {
    public static void main(String[] args) {
        //创建Runnable的子类(类,实现Runnable),通过构造方法传给Thread
        Thread t = new Thread(new Runnable() {
            @Override
            //重写run方法
            public void run() {
                System.out.println("hello");
            }
        });// ")"对应的时Thread构造方法的结束
        t.start();
    }
}

  • lambda表达式创建Runnable子类对象
public class demo3 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("hello");
        });
        t.start();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值