Java基础相关

JAVA基础-多线程和锁

2021-01-07  本文已影响0人  来lol里

对象锁一般有三种
1.锁非静态变量,非静态变量是实例自身变量,不会与其他实例共享,所以锁住实体内声明的非静态变量可以实现对象锁。锁住同一个变量的方法块共享同一把锁

  private Object obj =new Object();
  public void testSynchronized(){
        synchronized (obj);
        //do sth

    }

2.锁非静态方法,这个就比较直观了

  public synchronized void  testSynchronized(){
        //do sth
    }

3.锁this,this 指的是当前对象实例本身,所以,所有使用 synchronized(this)方式的方法都共享同一把锁。

 public void testSynchronized(){
        synchronized (this);
        //do sth
    }

类锁是加载类上的,而类信息是存在 JVM 方法区的,并且整个 JVM 只有一份,方法区又是所有线程共享的,所以类锁是所有线程共享的,同一时刻,只能有一个线程使用加了锁的方法或方法体,不管是不是同一个实例。
1.锁静态变量

    static Object obj =new Object();
public  void  testSynchronized(){
        synchronized(obj);
        //do sth
    }

2.锁静态方法

   public static synchronized void  testSynchronized(){
        //do sth
    }

3.锁xxx.class

  public static  void  testSynchronized(){
        synchronized (MainActivity.class){
            //do sth
        }
       
    }
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

任务来了首先进入到corePoolSize中,如果核心线程满了,进入workQueue队列里等待,如果队列满了,进入maximumPoolSize中等待,如果线程继续增加,则走handler(线程饱和策略)执行具体的饱和策略(默认四种
ThreadPoolExecutor.AbortPolicy 丢弃任务,抛出异常
ThreadPoolExecutor.DiscardPolicy丢弃任务,不过也不抛出异常,
ThreadPoolExecutor.CallerRunsPolicy该任务被线程池拒绝,由调用线程处理该任务 。ThreadPoolExecutor.DiscardOldestPolicy 抛弃队列最前面的任务,然后重新尝试执行任务)。
keepAliveTime表示空闲线程存活时间。

四种线程池的创建方式
通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

阿里推荐是用ThreadPoolExecutor自己创建,因为FixedThreadPool和SingleThreadExecutor => 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而引起OOM异常
CachedThreadPool => 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量的线程,从而引起OOM异常
这就是为什么禁止使用Executors去创建线程池,而是推荐自己去创建ThreadPoolExecutor的原因。
合理配置线程池参数:CPU密集型,IO密集型,混合型。

上一篇 下一篇

猜你喜欢

热点阅读