多线程:
程序:就是指为了完成某个特定任务而使用某种编程语言所开发的指令集合
进程:一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。
线程:进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。
与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,、或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
————————————————
synchronizde 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
修饰一个代码块
1、一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。
例子:
并行:多个cpu同时执行多个任务
并发:一个cpu执行多个任务
start 用于开启一个线程,并且start方法只能调用一次
两个功能 1 让线程进入等待队列 2 调用run方法
run方法,和正常方法一样调用 run方法里面存放的是线程任务
线程的调度模式:cpu会给线程分配时间片 一旦线程得到了时间片他就可以执行
那个线程抢到时间碎片该线程就执行,没有抢到时间碎片的就会处于一等待状态
线程的声命周期: 新建: 创建线程对象的时候
就绪: 线程对象调用完stact 方法后线程就会等待队列等待cpu给线程分配时间碎片
运行: 线程得到时间碎片
阻塞: 线程进入阻塞状态
死亡: 线程完成了run方法里面定义的任务 强制停止线程的运行 提供 stop()方法(当前被废弃)不使用
Thread的几个常用方法:
sleep()可以让当前进程进入休眠,直到休眠时间结束才让当前进程重新去竞争CPU时间片
yiele()可以让一个线程从运行状态回归到就绪状态yield()可以让当前线程释放时间碎片,进入就绪状态等待cpu的时间碎片
1、多线程的创建:四种
1、继承thread 类 实现 runnable 实现callable接口 线程池
thread类提供了一个静态方法名叫做getname()用于获取线程名称
class 类 extends thread {
public void run(){
}
}
start():启动当前线程, 调用线程中的run方法
run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
currentThread():静态方法,返回执行当前代码线程
getname():获取当前线程的名字
setname():这只当前线程的名字
yield():主动释放当前线程的执行权
join():在线程中插入执行另一个线程,该线程被阻塞,知道插入的线程完全执行完毕后,该线程才能继续执行下去
stop():过时方法,当执行此方法时,强制结束当前线程
sleep():线程休眠一段时间
isAlive():判断当前线程是否存活
两种调度方式
分时调度模式:是指让所有线程轮流获得cpu的使用权,且分配的时间时平均的
抢占调度模式:是指每条线程执行的时间,线程的切换都由系统控制,
在Java中锁就是一个对象synchronize(){}
同步代码块:就是将需要被同步的代码装在代码块里面
同步方法块:
}
死锁:定义
两个线程对象持有各自的锁,而去抢占对方的锁 线程T1 有锁1 线程T2 有锁2 线程1去抢锁2 线程2去枪锁1
解决方法:1、改变枷锁顺序 2、使用lock锁(手动锁自己 自己加锁 自己释放锁)
try和lock一样也是用于加锁,只是trylock有返回值如果加锁成功返回true失败false 注意:如果失败了就不能解锁了unlock
lock和synchronize区分:
trylock(long time,timeunit unti):和trylock类似,只是加入了时间即规定时间内加锁成功返回true
否则返回false,该方法会抛出一个异常Interrupteexception
1、synchronize是一个关键字,lock是一个接口
2、synchronize的加锁和释放锁是自动的,lock则相反
3、lock可以监听到他的锁状态
4、synchronize会造成死锁,lock不会
wait()用于当前线程进入阻塞状态,并且释放锁 并且它要抛出一个异常Interruptedexception
notify() 用于唤醒线程
wait()和notify()必须房子synchronize同步方法或者代码块里面
通过锁对象去调用wait和notfy方法
notify用于唤醒单个线程notify all用于唤醒所有线程
wait和sleep区别:
1、 sleep不会释放锁,wait会释放锁 2、sleep到时间自动唤醒,wait()需要notify()手动唤醒
futuretask可以用于接受callable
futuretask还提供了一个get方法---用于拿取返回值
futuretask实现了runable接口,对此它也是runable的一个实例对象
call方法用于执行线程任务,并且可以返回结果,并且该方法会抛出一个异常
Synchronized的特点:
- (1)、原子性:所谓原子性就是指一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。被synchronized修饰的类或对象的所有操作都是原子的,因为在执行操作之前必须先获得类或对象的锁,直到执行完才能释放。
- (1)原子性(2)、可见性:(3)、有序性:
死锁:定义
两个线程对象持有各自的锁,而去抢占对方的锁 线程T1 有锁1 线程T2 有锁2 线程1去抢锁2 线程2去枪锁1
解决方法:1、改变枷锁顺序 2、使用lock锁(手动锁自己 自己加锁 自己释放锁)
try和lock一样也是用于加锁,只是trylock有返回值如果加锁成功返回true失败false 注意:如果失败了就不能解锁了unlock
lock和synchronize区分:
trylock(long time,timeunit unti):和trylock类似,只是加入了时间即规定时间内加锁成功返回true
否则返回false,该方法会抛出一个异常Interrupteexception
1、synchronize是一个关键字,lock是一个接口
2、synchronize的加锁和释放锁是自动的,lock则相反
3、lock可以监听到他的锁状态
4、synchronize会造成死锁,lock不会
wait()用于当前线程进入阻塞状态,并且释放锁 并且它要抛出一个异常Interruptedexception
notify() 用于唤醒线程
wait()和notify()必须房子synchronize同步方法或者代码块里面
通过锁对象去调用wait和notfy方法
notify用于唤醒单个线程notify all用于唤醒所有线程
wait和sleep区别:
1、 sleep不会释放锁,wait会释放锁 2、sleep到时间自动唤醒,wait()需要notify()手动唤醒
futuretask可以用于接受callable
futuretask还提供了一个get方法---用于拿取返回值
futuretask实现了runable接口,对此它也是runable的一个实例对象
call方法用于执行线程任务,并且可以返回结果,并且该方法会抛出一个异常