多线程基础

多线程

1、普通方法调用和多线程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-waDlYlZJ-1603975644100)(E:\桌面\images\1603728306(1)].png)

  • 进程是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单位
  • 通常在 一个进程中可以包含若干个线程,一个进程中至少有两个线程(Main,GC)。线程是CPU调度和执行的单位

很多多线程是模拟出来的,真正的多线程是指有多个CPU,即多核,如服务器。如果是模拟出来的多线程,即在一个CPU的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所以就有同时执行的错觉。

  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制

  • 线程会带来额外的开销,如cpu调度时间,并发控制开销

  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

2、三种创建方式

Thread class – 继承Thread类

Runnable接口 – 实现Runnable接口

Callable接口 – 实现Callable接口

一般使用Runnable,java单继承多接口

API

Thread.currentThread().getName();
Thread.sleep();

2.1、Thread

  • 自定义线程类继承Thread类
  • 重写run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程

线程开启不一定执行,由cpu调度执行

class MyThread extends Thread{
    public void run (){}
}

class Test{
    psvm{
        MyThread my = new MyThread();
        my.run();
    }
}

2.2、Runnable

  • 定义类实现Runnable接口
  • 实现run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程
 class MyRunnable implements Runnable{
    public void run (){}
}

class Test{
    psvm{
        MyRunnable my = new MyRunnable();
        Thread thread = new Thread(my);
        thread.run();
        //  new Thread(new MyRunnable()).run();
    }
}

2.3、Callable

  • 实现Callable接口,需要返回值类型

  • 重写call方法,需要抛出异常

  • 创建目标对象t1

  • 创建执行服务:ExecutorService ser =Executors.newFixedThreadPool(1);

  • 提交执行:Future result =ser.submit(t1);

  • 获取结果:boolean r1=result.get();

  • 关闭服务:ser.shutdownNow();

3、Lambda表达式

函数式接口:接口只包含唯一一个抽象方法

4、线程状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gAwDhQGc-1603975644103)(E:\桌面\images\1603777623(1)].png)

public enum State{
    //新生
    NEW,
    
    //运行
    RUNNABLE,
    
    //阻塞
    BLOCKED,
        
    //等待,死死地等
    WAITING,
    
    //超时等待
    TIMED_WAITING,
    
    //终止
    TERMINATED;
}

5、线程方法

方法说明
setPriority(int newPriority)更改线程的优先级1~10,MIN_PRIORITY=1,MAX_PRIORITY=10,NORM_PRIORITY=5,setPriority(int);
static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠
void join()等待该线程终止,再执行其他线程,其他线程阻塞
static void yield()暂停当前正在执行的线程对象,但不阻塞,并执行其他线程。礼让线程,将线程从运行状态转为就绪状态。让cpu重新调度,礼让不太一定成功,看cpu
void interrupt()中断线程,不用这个方式
boolean isAlive()测试线程是否处于活动状态

6、守护线程

线程分为用户线程和守护线程(Deamon)

守护线程:

​ setDeamon(true); //默认false表示用户线程

7、线程同步

锁机制:synchronized,当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可

synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。

8、同步方法和同步代码块

同步方法:

public synchronized void test(){}

同步块:

synchronized(Obj){}

9、死锁

多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块同时拥有两个以上对象的锁时,就可能会发生死锁的问题

多个线程互相抱着对方需要的资源,然后形成僵持。

产生死锁的四个必要条件:

  • 互斥条件:一个资源每次只能被一个进程使用
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
  • 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

只要破坏其中的任意一个或多个条件就可以避免死锁的产生

10、Lock锁

可重入锁ReentrantLock

private final ReentrantLock lock =new ReentrantLock();
lock.lock();
lock.unlock();
lock.tryLock();

11、线程池

ExecutorService:线程池接口,常见子类ThreadPoolExecutor

  • void execute(Runnable command):执行任务/命令,没有返回值,一般用来执行Runnable
  • Future sumbit(Callable task):执行任务,有返回值,一般用来执行Callable
  • void shutdown():关闭连接池

Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值