进程 线程 多线程
我们打开一个软件其实就是添加了一个进程,支撑这个进程运行的叫线程,Cpu相当于一个工厂,进程相当于一个个车间,线程相当于每个车间的工人,每个进程享有Cpu内独立的空间,多个线程共享一个进程内存空间
进程:应用程序的执行实例,有独立的内存空间和系统资源
线程:进程基础之上,Cpu调度和分派的基本单位,执行运算的最小单位,可完成一个独立的顺序控制流程,
多线程:一个进程中同时运行了多个线程,完成不同的工作,则称为多线程,多个线程交替占用cpu资源,而非真正的并行执行。好处:充分利用Cpu资源,提升代码性能; 简化编程模型,更好的软件设计和架构;带来良好用户体验
Java提供了java.lang.Thread类,支持多线程编程;main()方法为主线程入口
方法:
void run() 执行任务操作的方法
void start() 使线程开始执行
void sleep(long millis) 在指定的毫秒数让正在执行的线程休眠
String getName() 返回该线程的名称
int getPriority() 返回该线程的优先级
void setPriority(int newPriority) 更改线程的优先级
Therad.State getState() 返回该线程的状态
boolean isAlive() 测线程是否处于活动状态
void join() 等待该线程终止
void interrupt() 中断线程
void yield() 暂停当前执行的线程对象,并执行其他线程
例:
共三种:常用的 继承Thread 实现Runnable接口,
第一种:继承Thread创建线程
继承java.lang.Thread类;
1.创建一个类继承Thread类。
2.重写run()方法,编写线程执行体。
3.创建线程对象,调用start()方法启动线程
特点:编写简单,可直接操作线程
适用于单继承
如果用extens实现线程会出现两个窗口一共20张票,凭空出现10张,在实际上是不存在的,不符合现实;使用第二种方法,实现Runnable接口即可解决
总结:一个是多个线程分别完成自己的任务(extens Thread), 一个是多个线程共同完成一个任务(Runnable)
总结:
1.继承Thread类,重写run()方法:便于代码复用
2.实现Runnbale接口,重写run()方法:用处广泛,便于扩展
3.实现Callbale接口,重写call()方法:特定场景需要返回值时可以用
创建、就绪、运行、阻塞、死亡。
线程调度:指按照特定机制为多个线程分配CPU使用权
方法:
void setPriority(int newPriority) 更改线程的优先级
static void sleep(long millis) 指定毫秒内让正在执行的线程休眠
boolean isAlive() 测线程是否处于活动状态
void join() 等待该线程终止
void interrupt() 中断线程
void yield() 暂停当前执行的线程对象,并执行其他线程
调整优先级:1~10区间
设置休眠:(模拟系统延迟)sleep跟wait工作中一般不允许使用,只在测试时使用
void yield()
线程礼让,让该线程处于就绪状态,不转为阻塞状态;只是提供一种可能,但是不能保证一定会实现礼让,缺点:线程1礼让线程2,但是线程2不一定会执行;就像过年拿压岁钱,人家塞给你“拿着拿着大过年的”,你能直接要么?“别别别,大可不必”。
void join() :
阻塞当前线程,直到其他线程执行完毕,当前线程才进入就绪状态,俗称插队!举例:某刀刀好友助力,助力只是提高优先级,花钱才是强行Join。
多线程共享操作数据时,引发冲突(如延迟,操作未全部完成)造成数据不安全
解决方案:实现线程同步:上锁
一、使用synchronized修饰符的方法控制对类成员变量的访问。
synchronized就是为当前的线程声明一把锁
1. 访问修饰符 synchronized 返回类型 方法名(参数列表){...}
或 synchronized 访问修饰符 返回类型 方法名(参数列表){....}
二、使用synchronized关键字修饰的代码块
synchronized(syncObject){ //需要同步的代码块 }
syncObject为需同步的对象,通常为this
常见线程安全的类型:
ArrayList-->Vector
HashMap-->HashTable (旧)
-->ConcurrentHashMap
StringBuilder-->StringBuffer