多线程基础

本文详细介绍了Java中的线程和进程概念,探讨了多线程的创建方式,包括继承Thread类、实现Runnable接口和Callable接口。还讲解了守护线程、线程安全问题及其解决方案、线程状态、优先级管理以及join()方法和yield方法。重点强调了多线程并发的三个特性:原子性、可见性和有序性。
摘要由CSDN通过智能技术生成
线程和进程
进程:

是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用 程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基 本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。

线程:

进程内部的一个独立执行单元;一个进程可以同时并发的运行多个线程,可以理 解为一个进程便相当于一个单 CPU 操作系统,而线程便是这个系统中运行的多个任务。

多线程的创建方式

第一种继承Thread类 重写run方法 (无法设置返回值)

实现Runnable接口,重写run方法 (无法设置返回值)

实现 implements Callable接口(可以存在线程返回值 Object)

实现Runnable接口比继承Thread类所具有的优势:
  1. 适合多个相同的程序代码的线程去共享同一个资源。

  2. 可以避免java中的单继承的局限性。

  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和数 据独立。

  4. 线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread 的类

守护线程

Java中有两种线程,一种是用户线程,另一种是守护线程。 用户线程是指用户自定义创建的线程,主线程停止,用户线程不会停止。 守护线程当进程不存在或主线程停止,守护线程也会被停止

thread1.setDaemon(true); //设置守护线程

线程安全相关问题

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静 态变量只有读操作,而无写 操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一 般都需要考虑线程同步, 否则的话就可能影响线程安全。

如何解决

当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容 易出现线程安全问题。 要解决上述多线程并发访问一个资源的安全问题,Java中提供了同步机制 (synchronized)来解决。

一.同步代码块 (自动锁) (重量锁)

二.同步方法

三.lock锁同步 (手动锁)

ReentrantLock lock = new ReentrantLock();
 lock.lock();
 sell(name);
 lock.unlock();

线程状态

状态描述:NEW(新建) 线程刚被创建,但是并未启动。

RUNNABLE(可运行) 线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。

BLOCKED(锁阻塞) 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。

WAITING(无限等待) 一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入Waiting状态。进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyAll方法才能够唤醒。

TIMED_WAITING(计时等待) 同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep 、Object.wait。

TERMINATED(被终止) 因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

wait() 让线程处于等待状态,并且释放当前锁资源 需要手动唤醒
sleep() 不会释放锁 让线程处于等待状态 自然醒来
  • 对于sleep()方法,首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

  • sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

    wait()是把控制权交出去,然后进入等待此对象的等待锁定池处于等待状态,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

  • 在调用sleep()方法的过程中,线程不会释放对象锁。而当调用wait()方法的时候,线程会放弃对象锁。

线程结束:

结束线程有以下三种方法: (1)设置退出标志,使线程正常退出。 (2)使用interrupt()方法中断线程。 (3)使用stop方法强行终止线程(不推荐使用Thread.stop, 这种终止线程运行的方法已经被废弃,使用它们是极端不安全的!)

Thread.sleep(1000l);
//中断线程
t.interrupt();
t.stop(); //废弃

线程优先级

现今操作系统基本采用分时的形式调度运行的线程,线程分配得到时间片的多少决定了线程使用处理器资源的多少,也对应了线程优先级这个概念。

在JAVA线程中,通过一个int priority来控制优先级,范围为1-10,其中10最高,默认值为5。

线程优先级 并不能觉得线程的执行顺序,只是让当前线程能够获得更多的cpu资源而已

优先级可以增加线程获取cpu资源的多少,但是不能决定线程的执行顺序

t.setPriority(1);  //获得的cpu资源多于 线程2
join()方法 (让线程顺序执行)

join作用是让其他线程变为等待。thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

yield方法

Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果) yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。

多线程并发的3个特性 (重点)

原子性 :即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要 么就都不执行

可见性:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即 看得到修改的值 (volitale)

有序性:程序执行的顺序按照代码的先后顺序执行

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值