JAVA多线程并发编程学习笔记1——进程和进程安全

本文介绍了JAVA并发编程的基础知识,包括进程与线程的概念、优缺点,Java中的线程操作,以及线程安全的重要性。详细讲解了线程安全的三大特性:原子性、可见性和有序性,强调了在多线程环境下确保数据一致性的重要机制。

JAVA并发编程

1. 介绍

1.1 进程与线程

1.1.1 概念

进程:计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位(比如内存、文件句柄、安全证书)。程序在各自的进程上运行,可以简单理解为运行的程序。

线程:是进程的一个执行单元,以单一顺序的控制流作为进程的执行分支。共享进程范围内的资源(比如内存、文件句柄),但都有自己的程序计数器、栈和本地变量。

1.1.2 线程的优点
  • 降低开发和维护的开销
  • 在GUI程序中改进用户接口的响应性
  • 在服务器应用中提高资源的利用率和吞吐量
1.1.3 线程的风险
  • 安全危险:线程交替占有运行时,导致意外结果。
  • 活跃度的危险:多线程带来活跃度失败,如死锁、饥饿、活锁。
  • 性能危险:上下文切换(挂起当前线程,运行另一个线程)的频繁进行导致巨大的系统开销;同步机制限制编译器的优化。
1.1.4 线程引入的开销
  • 上下文切换
  • 内存同步
  • 阻塞
1.1.5 Java中的线程

​ JVM启动时会创建一个主线程,该主线程负责执行main方法;以及一些进行自身的常规管理线程(如垃圾回收、终结处理)。

1.2 并行与并发

  • 并行(parallel):同时处理多个任务
  • 并发(concurrent):有处理多个任务的能力,但不一定是同时。

1.3 Java线程操作

1.3.1 创建与启动
  • 创建一个线程就是创建Thread类对象,可以直接定义Thread类子类或定义Runnable接口的实现类,并重写run方法,即线程要执行的任务。

    // 方法一
    public class MyThread extends Thread{
        @override
        public void run(){
            //do something in a thread
        }
    }
    
    //方法二
    public class MyRunnable implements Runnable{
        @override
        public void run(){
            //do something in a thread
        }
    }
    
  • 启动线程即调用Thread类的start()方法。

    //方法一
    MyThread myThread = new MyThread();
    myThread.start();
    
    //方法二
    MyRunnable myRunnble = new MyRunnable();
    Thread thread = new Thread(myRunnable);
    thread.start();
    
    //或直接创建Runnable的匿名类对象或lambda表达式
    new Thread(() -> {
        //do something in a thread.
    }).start;
    
1.3.2 Thread类常用方法
方法名返回值描述
currentThread()static Thread返回执行当前代码的线程
getName()String返回线程名称
setName()void设置线程名称
getId()long返回线程的唯一标识
isAlive()boolean判断是否处于活动状态
sleep(long)static void让当前线程休眠数毫秒
yield()static void放弃当前CPU资源
setPriority()void设置优先级1-10,越大越优先
getPriority()int返回线程优先级
interrupt()void设置中断标志为true,并不一定中断线程
isInterrupt()boolean判断线程中断标志
interrupted()static boolean判断当前线程中断标志
setDaemon(boolean)void设置线程为守护线程
isDaemon()boolean判断是否为守护线程
getState()Thread.state返回线程状态
join(),join(long)void在主线程中调用其他线程的join()可使主线程等待,执行调用join的线程
1.3.3 线程的生命周期(状态)

​ 线程的生命周期就是线程的状态,由Thread.state枚举类型定义,有以下几种:

类型描述
NEW创建线程后未启动的状态
RUNNABLE线程启动后的状态,包含ready和running,调用yield()会转成ready
BLOCKED阻塞状态,发起阻塞I/O操作或申请锁后
WAITING执行wait(),join()后会使调用线程或所在线程等待
TIME_WAITED执行wait(long),join(long)后会使调用线程或所在线程等待有限时间
TERMINATED终止状态,run()程序运行结束后

2 线程安全

2.1 概念

2.1.1 线程安全定义

当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用方代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类时线程安全的。即线程安全的类封装了必要的同步。

2.1.2 非线程安全

非线程安全主要是指多个线程对同一个对象的实例变量进行操作时,会出现值被更改并且值可能不同步的情况。

2.1.3 线程安全体现

三个方面:原子性、可见性和有序性

2.2 原子性

2.2.1 含义

原子性即不可分割性,体现为访问某个共享变量的操作从其他线程来看,要么已经执行完毕,要么尚未发生。

2.2.2 例子

对变量自增包含“读-改-写”三个操作,在缺乏同步的情况下会出错。

2.2.3 实现方法
  • CAS(Compare And Swap)

2.3 可见性

2.3.1 含义

在多线程环境中,一个线程对某个共享变量更新之后,后续其他线程可能无法立即读到更新的结果。

  • 如果一个线程更新一个变量后,其他线程可以读到更新结果,则是可见的。
2.3.2 实现方法
  • volatile

2.4 有序性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值