part A进程、线程和多线程
进程:正在运行的程序
线程:进程中独立运行的子任务
运行main函数的线程是主线程,也就是main线程,该线程的名字是main,跟main方法无关。
实现多线程的方式
1.继承Thread类(Thread类实现了runnable接口)局限于java单继承,不能继承其他类,所以一般都使用第二种方法。
2.实现runnable接口
多线程代码的运行结果与代码执行顺序或者调用顺序无关。线程的调用是随机的。
线程安全问题:多个线程对同一个对象中的同一个实例变量进行操作时会出现值被修改,但修改不同步的情况。
currentThread() 方法,返回一个正在被执行的线程
this.getName()方法被Thread-0调用
线程中的各种方法
getName() 返回正在运行的线程的名字
isAlive() 判断是否处于活动状态,线程从创建到死亡之前都返回true,一旦线程执行完,线程进入死亡状态就是false
sleep() 休眠线程,毫秒内让当前执行的线程休眠,时间过了就会自动,这个方法是放锁的。
getId() 获得执行线程的id
suspend() 暂停线程,可以用resume()回复线程执行.但是这两个方法是会对公共的同步对象独占,其他线程就无法访问这个对象,不同步,最后作废。
yield() 礼让线程,让其他的任务先执行,导致本任务用时变长
setDaemon(boolean on) 守护线程随着主线程停止而停止守护线程
join() 等待该线程终止。加入线程
wait() 线程等待
notify() 线程唤醒
notifyAll() 线程唤醒
线程优先级
线程优先级分为1-10十个等级,默认5,超出范围会抛出一个IllegalArgumentException
getPriority()
setPriority()
优先级是可以继承的;例如线程A在运行中启动线程B,线程B的优先级和A是一样的。
高优先级的线程大部分先执行完,但不代表高优先级就要全先执行完。优先级和代码执行顺序没关系。优先级具有随机性
终止线程的三种方法:
1.等run方法完成
2.使用stop强行终止(不被推荐,因为这个方法不是线程安全的)
3.使用interrupt来中断线程(这个方法被执行的瞬间总是再运行多几句,所以可以通过先sleep()然后interrupt();当然还可以通过interrupted(),return来停止线程)
part B 多线程同步
实现线程的方法中的变量(局部变量)不存在非线程安全问题,是线程安全的。
实例变量和静态变量是非线程安全的。
一、Synchronize同步方法结论
1.A线程先持有对象的Lock锁,B线程可以以异步的方式调用OIbject对象的非Synchronize类型的方法。
2.A线程先持有对象的Lock锁,B线程调用OIbject对象的Synchronize类型的方法需要等待,就是同步。
3.关键字Synchronize拥有锁重入的功能,就是说当线程得到一个锁对象的时候,再次请求此对象锁的时候可以再次得到对象的锁,
即是说,在Synchronize内部调用本类的其他Synchronize方法时候,是一定能得到锁的。再次获得自己的内部锁。
4.当存在父子继承关系时,子类可以通过“可重入锁”调用父类的同步方法。
5.多个线程执行的代码其中有一个在运行的时候出现异常,其持有的锁会自动释放,其他的线程会运行。
6.同步不可以被继承,父类的方法中有Synchronize,子类没有Synchronize,则会导致调用子类方法的时候会有非同步安全问题
Synchronize方法的弊端:从运行时间上来看,运行时间太长,解决方法:使用同步代码块
Synchronize(object){......}
二、Synchronize(对象监视器object){..}同步代码块:
Synchronize同步方法有两个作用:
1)对其他Synchronize同步方法或者Synchronize(this)同步代码块调用呈阻塞状态,
2)同一时间只有一个线程可以执行Synchronize同步方法代码。
Synchronize(this)同步代码块有两个作用:
1)对其他Synchronize同步方法或者Synchronize(this)同步代码块调用呈阻塞状态,
2)同一时间只有一个线程可以执行Synchronize(this)的代码。
Synchronize(x)
1)多个线程持有同一个对象监视器object的时候,同一时间只有一个线程可以执行Synchronize(对象监视器)的代码块