黑马程序员_多线程

  多线程是java中的技术。所谓多线程就是合理利用cpu达到一个看起来像是多个程序“同时”运行的效果,其实是cpu在做着线程的快速切换。
  多线程有着专门的启动方式,开启多线程要使用start方法。
  在多线程中存在着一种后台线程,后台线程依赖前台线程,当前台线程结束后,该进程只存在后台线程的话那么这个线程将结束。
会结束。
  创建一个线程类有两种方法:
1,直接继承Thread类;
2, 实现Runnable接口,然后用new Thread(实现Runnable接口的类的对象)来产生一个线程类。
  Thread类中的setDaemon(true)设置一个线程为后台线程,该方法必须在线程启动之前调用,也就是在调用start()方法之前调用。如果一个进程中只有后台线程在运行,这个进程就会结束。
  thread1.join()的作用是把thread1所对应的线程合并到调用thread1.join()的线程中。
  yield()方法可以让当前正在运行的线程对象临时暂停,让别的线程运行。
  sleep(...)方法可以让当前正在运行的线程进入睡眠状态。
  获取和更改线程的优先级分别用Thread对象的getPriority()方法和setPriority(int newPriority)方法。线程的默认优先级的值是5。
  使用Runnable接口创建多线程,适合多个相同程序代码的线程去处理同一份资源的情况。还可以避免由于java的单继承特性带来的局限。事实上,几乎所有的多线程应用都可用Runnable接口方式。
  在多线程中,由于cpu的切换问题会造成安全隐患,为了解决安全隐患我们给某段程序“上锁”,即关键字:Synchronized。被关键字synchronized所修饰的某段程序在执行的时候只允许一个线程执行,这种线程被称之为同步。“上锁”的方法并不是只有Synchronized这一种,还可以使用ReentrantLock来自定义一个“lock”“unlock”锁。他们的区别如下:
1、ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断。如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情
   ReentrantLock获取锁定与三种方式:
    a)  lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
    b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
    c)tryLock(long timeout,TimeUnit unit),   如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
    d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断
2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中
3、在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;
   Object类里面有几个方法是用于线程通信的:wait(),notify(),notifyAll()。但是这些方法只能在被synchronized修饰的方法或者代码块中调用。wait()是等待命令,notify()是唤醒最先等待的线程,notifyall()是唤醒所有等待的线程。因此使用Synchronized的时候有事会发生死锁现象,举例如下:
  String str1 = "";
  String str2 = "";


  while(true)
 {
   synchronized(str1) 
    {
       ...
      synchronized(str2)
       {
         ...
       }
       ...
    }
 }


  while(true) 
 {
    synchronized(str2)
     {
        ...
        synchronized(str1)
        {
         ...
        }
        ...
     }
  }
  在上述例子中,当两个while块里面的代码分别由两个线程执行,那么就形成了死锁。在使用多线程的时候一定要避免死锁的发生。
 

















资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 HttpServletRequestWrapper 是 Java Servlet API 中的一个工具类,位于 javax.servlet.http 包中,用于对 HttpServletRequest 对象进行封装,从而在 Web 应用中实现对 HTTP 请求的拦截、修改或增强等功能。通过继承该类并覆盖相关方法,开发者可以轻松地自定义请求处理逻辑,例如修改请求参数、添加请求头、记录日志等。 参数过滤:在请求到达处理器之前,可以对请求参数进行检查或修改,例如去除 URL 编码、过滤敏感信息或进行安全检查。 请求头操作:可以修改或添加请求头,比如设置自定义的 Content-Type 或添加认证信息。 请求属性扩展:在原始请求的基础上添加自定义属性,供后续处理使用。 日志记录:在处理请求前记录请求信息,如 URL、参数、请求头等,便于调试和监控。 跨域支持:通过添加 CORS 相关的响应头,允许来自不同源的请求。 HttpServletRequestWrapper 通过继承 HttpServletRequest 接口并重写其方法来实现功能。开发者可以在重写的方法中添加自定义逻辑,例如在获取参数时进行过滤,或在读取请求体时进行解密。当调用这些方法时,实际上是调用了包装器中的方法,从而实现了对原始请求的修改或增强。 以下是一个简单的示例,展示如何创建一个用于过滤请求参数的包装器: 在 doFilter 方法中,可以使用 CustomRequestWrapper 包装原始请求: 这样,每当调用 getParameterValues 方法时,都会先经过自定义的过滤逻辑。 HttpServletRequestWrapper 是 Java Web 开发中一个强大的工具,它提供了灵活的扩展性,允许开发者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值