0
点赞
收藏
分享

微信扫一扫

多线程——java学习笔记

古得曼_63b6 2022-04-29 阅读 57

基本概念

  • 程序:计算机语言编写的一组指令的集合。
  • 进程:程序在运行内存中的产生、存在、消亡的过程。
  • 线程:程序内部的执行路径。
  • 多线程:同时并行执行多个线程;每个线程拥有独立的运行栈、程序计数器,共享堆、方法区。

java程序至少有三个线程:main()主线程、gc()垃圾回收进程,异常处理线程。

单核CPU与多核CPU的多线程

单核CPU多线程:断续执行多个线程(暂停一个线程,执行另一个线程),同一时间执行一个线程,因时间单元小,故宏观上表现为多线程,是一种假的多线程,实质为单线程,是一种并发。

多核CPU多线程:同定义的多线程,是一种并行,但每个核也可以执行假的多线程,即多核CPU具备并发和并行。

多线程优点

  1. 提高应用程序的相应,增强用户体验;
  2. 提高CPU的利用率,减少闲置;
  3. 改善程序结构,利于理解和修改。

多线程使用场景

  1. 程序需要同时执行多个任务;
  2. 存在等待任务时,如用户输入、文件读写操作、网络操作、搜索等;
  3. 需要后台运行程序。

多线程的创建和使用

一个线程对应一个线程类的一个对象,多个对象对应多个线程。

方式一

  1. 创建一个继承于Thread类的子类;
  2. 重写run方法:public void run() {线程执行的操作}
  3. 主类中创建线程对象;
  4. 执行该线程:对象名.start(); // 不能直接调用run方法,否则仍为main线程;同一个对象不能重复执行该线程,否则报异常。

获取当前当前线程的默认名:Thread.currentThread().getName()。//默认名为Thread-0, Thread-1, Thread-2…

注意:该方式创建的多线程,共享数据和同步监视器都必须声明为静态的,否则它们不唯一。

方式二

优先选择这种方式,它可以把类的对象和线程的对象分隔开,更能体现封装的特性。

  1. 创建一个实现了Runnable接口的类;
  2. 重写run方法:public void run() {线程执行的操作}
  3. 主类中创建该类的对象;
  4. 该对象作为有参构造器参数,创建Thread类对象thread;
  5. 执行该线程:thread.start();

Threa的常用方法

Thread类的静态方法

也可通过继承Thread类的子类直接调用

  • Thread.currentThread() == 返回对当前正在执行的线程对象的引用
  • Thread.sleep(毫秒数) == 使当前正在执行的线程以指定的毫秒数暂停
  • Thread.yield() == 释放当前CPU的执行权,随机继续执行线程

Thread类的动态方法

也可通过继承Thread类的子类直接调用

  1. 创建对象:见多线程的创建
  2. 调用对象的方法
  • thread.getName() == 返回此线程的名称
  • thread.setName(线程名称) == 设置此线程的名称
  • thread.isAlive() == 判断此线程是否存活,是则返回true
  • thread.join() == 暂停当前线程并执行thread线程至thread线程消亡再继续执行当前线程

线程的优先级

线程的优先级是指线程优先执行的概率(0, 1)高低,并不是一定优先执行。

优先级常量

MAX_PRIORITY == 最大优先级:10

MIN_PRIORITY == 最小优先级:1

NORM_PRIORITY == 普通优先级(默认):5

获取和设置优先级

thread.getPriority() == 返回此线程的优先级

thread.setPriority() == 设置此线程的优先级

线程的生命周期

在这里插入图片描述

多线程的安全性

普通的多线程存在不安全问题:一个线程操作共享数据时出现阻塞,其它线程也参与进来操作共享数据,导致共享数据未及时改变出现重复,或导致操作完后共享数据越界。

解决原理:使操作共享数据的语句变成单线程的,即共享数据同步,只能同时被单个线程操作。

同步语句

synchronized(同步监视器){同步代码}

同步监视器:任何类的同一个对象,又称锁,同步语句执行时占用锁,执行完释放锁。可以考虑用this类名.class替换。

同步方法

把同步代码提取出来,创建一个同步方法,然后调用该方法;这种同步方式给整个方法上锁,相对同步语句有一定局限性。

方式一的同步方法:private static synchronized void 方法名(){同步代码} // 必须声明为静态方法;隐含同步监视器当前类.class

方式二的同步方法:private synchronized void 方法名(){同步代码} //隐含同步监视器this

Lock锁

JDK5新增,一种手动锁,即手动调用方法获得锁和释放锁,优先选择这种同步方式。

  1. 创建Lock对象(同步监视器):private static Lock lock = new ReentrantLock(); // 多态,方式一线程

private Lock lock = new ReentrantLock(); // 多态,方式二线程

  1. 创建Lock语句及调用方法:try{lock.lock(); 同步代码}finally{lock.unlock();}

死锁

多个线程执行同步代码时占用了对方的同步数据或同步监视器,一直进入阻塞状态。

避免死锁的办法:减少同步数据的定义;减少同步嵌套。

举报

相关推荐

0 条评论