用实现runnable接口的方法创建线程时要,

  用实现runnable接口的方法创建线程时要,

  00-1010多线程run方法中如何直接调用服务业务类要注意下图:线程启动的四种方式使用@Aysnc注释实现多线程用户线程和守护线程的区别;Java锁的六种状态;睡眠和等待的四种拒绝策略;为什么wait(),notify()和notifyAll()在对象中,而不在线程类中?

  

目录

Java多线程运行方法使用服务业务类,导致java.lang.NullPointerException异常。这是因为spring注入的业务类是null,或者直接new的业务对象也是null。

 

  多线程为了线程安全会防止注入,所以当你想使用服务业务类的时候,你需要使用ApplicationContext获取bean方法来获取服务类。

  获取ApplicationContext的类实现ApplicationContextAware接口,如下所示:

  导入org . spring framework . beans . beans exception;导入org . spring framework . context . application context;import org . spring framework . context . applicationcontextaware;公共类ApplicationContextUtil实现ApplicationContextAware { private static application context context;public void setApplicationContext(application context context)抛出beans exception { this . context=context;}公共静态application context get context(){ return context;}}然后使用上述方法在run方法中创建一个业务对象,如下所示:

  XXXServiceI xxxService=applicationcontextutil . get context . get bean(XXXServiceI . class);这样商务舱就可以正常使用了。

  

多线程run方法中直接调用service业务类应注意

 

  

图解如下

 

  00-1010 1.继承Thread类,重写Thread的run方法,在run方法中操作,用start方法启动线程。

  2.继承runnable接口,实现run方法,在Run方法中操作。需要传入当前类的instance对象来创建一个线程实例,然后调用start方法来启动线程。

  3.实现Callable接口并重写call()方法。需要注意的是,前两个方法是直接执行的,没有任何响应。但是实现Callable接口和重写call()方法需要等待线程响应,所以虽然启动了其他线程,但是都是一个线程执行,不是标准的多线程。

  4.线程池

  00-1010在同一个类中,引用方法B的方法A加上异步@Async注释将无效。

  添加的@Async方法和调用方不能在同一个类中。

  00-1010 Java中创建的默认线程是创建一个用户线程,比如newthread.start。

  Thread thread=新线程();//默认为false,均为用户线程thread . set daemon(true);//表示设置为守护线程. set daemon(false);//表示设置为用户线程no,zhi随着其他线程的死亡而死亡。刀死的情况只有两种。一种是运行过程中因异常而终止,另一种是程序正常执行,线程在用户线程.死亡

  trong>:随着用户线程的死亡而死亡,当用户线程死完了守护线程也死了,比如gc垃圾回收线程。用户线程存在,那gc就有活着的必要,反之就没用了。

 

  

线程的六种状态

1. New:初始状态,线程被创建,没有调用start()

 

  2. Runnable:运行状态,Java线程把操作系统中的就绪和运行两种状态统一称为运行中

  3. Blocked:阻塞,线程进入等待状态,线程因为某种原因,放弃了CPU的使用权

  阻塞的几种情况:A. 等待阻塞:运行的线程执行了wait(),JVM会把当前线程放入等待队列B. 同步阻塞:运行的线程在获取对象的同步锁时,如果该同步锁被其他线程占用了,JVM会把当前线程放入锁池中C. 其他阻塞:运行的线程执行sleep(),join()或者发出IO请求时,JVM会把当前线程设置为阻塞状态,当sleep()执行完,join()线程终止,IO处理完毕线程再次恢复4. Waiting:等待状态

  5. timed_waiting:超时等待状态,超时以后自动返回

  6. terminated:终止状态,当前线程执行完毕

  

 

  

Java锁的可重入性

java锁的可重入性机制可以解决下面这个问题,直接上代码:

 

  

 public class Demo1 { public synchronized void functionA(){ System.out.println("iAmFunctionA"); functionB(); } public synchronized void functionB(){ System.out.println("iAmFunctionB"); }

假设Java没有提供synchronized 强制原子性的内部锁机制:functionA()和functionB()都是同步方法,当线程进入funcitonA()会获得该类的对象锁,这个锁"new Demo1()",在functionA()对方法functionB()做了调用,但是functionB()也是同步的,因此该线程需要再次获得该对象锁(new Demo1()),但是JVM会认为这个线程已经获取了此对象的锁,而不能再次获取,从而无法调用functionB()方法,从而造成死锁。

 

  

 

  

线程池的四种拒绝策略

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

 

  ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

  ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。

  ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务

  ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

  

 

  

sleep和wait的区别

sleep是线程中的方法,但是wait是Object中的方法sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中sleep不需要被唤醒,但是wait需要

 

  

为什么wait(),notify(),notifyAll()在对象中,而不在Thread类中

java中锁的级别是对象级而不是线程级,每个对象都有锁,通过线程获得。如果wait()方法在线程中,线程正在等待的是哪个锁就不明显了。

 

  以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: