多线程的详解

概述

什么是线程

假如我们我们10个集装箱,需要把从A地运往B地,但是我们只有一辆车,就必须一个一个的箱子运过去,,但是如果我们又10个辆车就可以一起运过去。在程序中如果不开通线程,那我们只有1辆车,如果开通了10个线程,我们就拥有了10辆车,一起运过去。效率大大提高。

注意:很多多线程是模拟出来的,真正的多线程是多个cpu,即多核,如服务器。如果模拟出来的多线程,即只有一个cpu的情况下,在同一时间点,cpu智能执行一个代码,因为切换的很快,所以造成了同时执行的假象

本章核心概念

  1. 线程是独立的执行程序
  2. 在程序运行的时候,即使自己没有创建线程,后台也会有多个线程在同事执行,如主线程main(),java的垃圾回收机制GC线程等等,
  3. 一个进程中,如果开了多个线程,线程的运行由调度器安排,调度器与操作系统相关的,线程运行的先后顺序无法人为的干预
  4. 当同一个资源,多个线程同时操作的时候,特别是对改资源进行增删改的时候,需要加入线程并发机制

线程的创建

  1. 继承Thread类(不建议使用,单继承有局限性)
//创建线程一:继承Thread类,重写run方法,调用start方法开启线程
public class Thead1 extends Thread{
    @Override
    public void run() {
        System.out.println("这是一个继承Thread类的线程");
    }

    public static void main(String[] args) {
        Thead1 thread1=new Thead1();
        thread1.start();
    }
}
  1. 实现Runnable接口 (推荐使用,避免了单继承的局限性,灵活方便,方便同一个对象多个线程使用 )
//创建线程二:实现Runnable接口,重写run方法,创建个Thread 对象,然后将类赋予这个Thread类,然后start
public class Thead2 implements Runnable {

    @Override
    public void run() {
        System.out.println("这是一个继承Thread2类的线程");
    }
    public static void main(String[] args) {
        Thead2 thread_run=new Thead2();
        Thread thread=new Thread(thread_run);
        thread.start();
    }
}
  1. 实现Callable接口
创建线程:实现Callable<T>接口
class Thead3 implements Callable<Boolean> {

    @Override
    public Boolean call() throws Exception {
        System.out.println("这是一个Callable的线程");
        return true;
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Thead3 thread_run1=new Thead3();
        Thead3 thread_run2=new Thead3();
        /**
         * 创建执行服务
         */
        ExecutorService executorService= Executors.newFixedThreadPool(2);
        /**
         * 提交执行
         */
        Future<Boolean> f1= executorService.submit(thread_run1);
        Future<Boolean> f2= executorService.submit(thread_run2);
        /**
         * //获取返回值
         */
        Boolean aBoolean = f1.get();
        Boolean bBoolean = f2.get();
        /**
         * 关闭服务
         */
        executorService.shutdown();
    }

Callable接口的好处:1:有返回值 2、可以抛出异常 3、可以定义同时能够执行的线程个数。如服务的线程数量只有2个,但是提交了3个线程跑,必须等前面的线程跑完后,才会执行第三个线程

线程的五大状态

在这里插入图片描述

线程的方法

方法说明
setPriority(int newPriority)更改线程的优先级
static void sleep(long millis)让当前线程休眠millis毫秒(抱着锁睡觉,不会释放锁)
static void wait(long millis)让线程等待(会释放资源)
void join()等待该线程终止
static void yield()暂停当前正在执行的对象,执行其他线程
void interrupt()中断线程(不推荐使用这个)
void isAlive()测试线程是否处于活跃状态
void stop() /destroy()停止线程(目前已经处于废弃状态不再使用这个方法了)
  1. 线程的停止(不建议使用stop或者destroy方法,建议用一个标志,让线程自动停止)
    例如:
class TestThead implements Runnable {
    //设置一个标志位
    private boolean flag=true;
    @Override
    public void run() {
        while (flag){
            System.out.println("这是一个TestThead线程");
        }
    }
    public void stop(){
        flag=false;
    }

    public static void main(String[] args) throws InterruptedException {
        TestThead t=new TestThead();
        new Thread(t).start();
        Thread.sleep(2000);
        t.stop();
    }
}
  1. 线程的礼让yield

线程礼让就是让当前的线程暂停,从运行状态变成就绪状态,但是不阻塞,让cpu重新调度,大家一切回到同一起跑线上,当然也有可能cpu还是让礼让的线程先跑也可能,看cpu心情

  1. 线程join
join 方法就是插队,它就是vip,先执行它,然后其他人再执行
  1. 线程的优先级

setPriority(int newPriority) 里面的参数就是优先级,优先级最小是1,最大是10.
优先级越高,先执行的概率越大,(注意:不是优先级高的一定先执行)

线程的同步

当多个线程同时操作一个资源的时候,会出现信息不对称的情况发生,(并发)所以必须解决这个问题,就是线程同步了

  1. synchronized

每个对象都有一把锁,引入synchronized锁机制,当一个线程获得对象 的排它锁,其他线程无法进入,它一个人独占资源

  • synchronized同步方法(缺陷:如果一个大方法加入synchronized 关键字,会大大的影响效率)
 public synchronized void  stop(){
  
    }
  • synchronized同步代码块
//obj是一个对象,将这个对象锁住,不让其他线程对他进行操作
 synchronized(obj){

        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值