2022-08-03 第六小组 瞒春 学习笔记

学习目标:

  • 继续深入掌握多线程

学习内容:

2022-08-03 第六小组 瞒春 学习笔记_第1张图片

 

  1. 锁、死锁
  2. 线程重入、推出

  1. synchronized

重量级的锁,jdk1.6对synchronized进行优化 为了减少获得锁和释放锁带来的性能的消耗,引入了偏向锁和轻量级锁

synchronized 三种加锁方式:

  1. 修饰成员(实例)方法  作用于当前实例加锁,进入同步代码之前要获得当前实例的锁
  2. 静态方法:作用域当前类对象加锁,进入同步代码前要获得当前类对象的锁
  3. 代码块:指定加锁对象,给指定的对象加锁,进入同步代码块之前要获得给定对象的锁

synchronized(){}

1.创建一个对象

2.类对象  Ch01.class

3.当前实例this

对象:

  1. 实例方法:调用该方法的实例
  2. 静态方法:类对象
  3. this:代表调用该方法的实例对象
  4. 类对象:

操作共享数据的代码  

共享数据:多个线程共同操作的变量,可以充当锁

当使用synchronized 锁的东西就是this(当前对象)

同步代码块使用:

private static Object obj=new Object();

public void run(){

sychronized(obj){}   (Ch02.obj)

}

Thread t1=new Thread(new window(“窗口一”))

也可以在obj的地方加入类对象

window.class 不需要加入新对象

1.同步方法依然会涉及到同步锁对象,不需要写出来

2.非静态方法的同步锁就是this

  静态的同步方法,同步监视器就是类本身

同步代码块

  1. 要选好同步监视器(锁)推荐使用类对象,第三方对象,this
  2. 实现箭扣创建的线程类中。同步代码块不可以用this充当同步锁

用了同步可以解决线程安全问题,但是只有一个线程可以参与,相当于单线程过程,效率低

synchronized只针对于当前JVM可以解决线程安全问题 也就是不可以跨JVM解决问题

死锁 

死锁情景:多个线程同时被阻塞,他们中的一个或者多个都在等待某个资源的释放,由于线程无限期的堵塞,程序就不可能正常终止。

java死锁产生的必要条件:

  1. 互斥使用,当资源被一个线程使用(占用),别的线程不能使用
  2. 不可抢占,资源的请求者不能强制从占有者中抢夺资源,资源只能从占有者手动释放
  3. 请求和保持
  4. 循环等待,存在一个等待的队列。p1占有p2资源 p2占p3 p3 占p1 都不释放形成等待环路

线程重入

任意的线程拿到锁之后,再次获得的时候不会被该锁阻碍

线程不会被自己锁死,这叫线程的重入,synchronized可重入锁

jdk1.5之后锁升级

  1. 无锁,不加锁
  2. 偏向锁:不锁锁,当只有一个线程争夺时,会偏向或一个线程,这个线程不加锁
  3. 轻量级锁:少量线程来了之后,先尝试自旋,不挂起线程。
  4. 重量级锁:排队挂起(暂停)线程 (synchronized)

挂起线程和恢复线程需要转入内核态中完成这些操作,会给系统的并发现带来很大压力,在许多应用上共享数据的锁定状态,只会持续很短的时间,为了这段时间去挂起和恢复并不值得,我们可以让后面的线程等待一下,不用放弃处理器的执行时间。锁为了让线程等待,我们只需要让线程执行一个循环,自旋【自旋锁】

Object类对多线程的支持

Object的成员方法

wait();   wait(long timeout ); (搁多久进来,可主动提前叫进来) 当前线程进入等待状态

notify();唤醒正在等待的下一个线程    notifyAll();   唤醒正在等待的所有线程

线程间的通信:两条线程共同运行,线程A如果先走,线程B就要等待,A走完唤醒B,B走

方法总结:

  1. Thread两个静态方法:

sleep释放CPU资源,但是不会释放锁

yield方法,释放CPU的执行权,但是保留CPU的执行资格,不常用

  1. join方法:yield出让了执行权,join就加入进来
  2. wait:释放CPU的资源,释放锁

notify 唤醒等待中的线程

notifyAll:唤醒等待中的所有线程

面试题:sleep和wait 区别

  1. 出处  2.锁的控制

线程的退出

使用退出标志来让线程正常推出,run方法结束后线程终止

interrupt方法 中断线程

/*Class MyThread extends Thread{

private boolean flag =true}



public void StopThread(){  停止方法

this flag=false; }*/

thread.interrupt();
参考

interrupt方法会抛出异常,捕获后再做停止线程的逻辑即可

如果whlie(true)运行的状态,interrupt叫不醒 别在main加死循环
建议用volatile volatile修饰一个属性 就是把它写进了内存不是缓存

线程的常用方法:

Thread类中的方法

  1. start:启动当前线程,执行run方法
  2. run;
  3. currentThread 静态方法,获取当前正在执行的线程
  4. getName() 获取当前线程的name 这几个可以直接写
  5. getId() 返回此线程的唯一标识
  6. setName() 设置当前线程的name
  7. getPriority() 获取当前线程的优先级
  8. setPriority(int) 设置当前线程的优先级
  9. getState() 获取当前线程的生命周期
  10. interrupt() 中断线程的执行
  11. inetrrupted() 查看当前线程是否被中断

枚举:天生构造器私有化,适合单例模式


学习时间:

  • 上午:7:30-12:00
  • 下午:1:30-5:00
  • 晚上:6:00-11:00

学习产出:

  • 进一步的认识了锁,并且学习了死锁
  • 认识了线程的重入、推出 具体代码有待提高

你可能感兴趣的:(java,jvm,servlet)