多线程为了线程安全会防止注入,因此在想使用service业务类时,需要使用applicationcontext的方式获取bean的方法获取service类。
获取applicationcontext的类要实现applicationcontextaware接口,如下:
import org.springframework.beans.beansexception;import org.springframework.context.applicationcontext;import org.springframework.context.applicationcontextaware; public class applicationcontextutil implements applicationcontextaware { private static applicationcontext context; public void setapplicationcontext(applicationcontext context) throws beansexception { this.context = context; } public static applicationcontext getcontext() { return context; }}
然后在run方法里使用以上方法创建业务对象,如下:
xxxservicei xxxservice = applicationcontextutil.getcontext.getbean(xxxservicei.class);
这样就能正常使用该业务类了。
图解如下
多线程知识点线程启动的四种方式1.、继承thread类重写thread的run方法,在run方法中进行操作,用start方法启动线程
2、继承runnable接口,实现run方法,在run方法中进行操作,需要传入当前类的实例对象创建一个thread实例,然后调用start方法启动线程
3、实现callable接口,重写call()方法,需要注意的是,前两种方法都是不需要响应的,直接就执行了,但是实现callable接口,重写call()方法则是需要等待线程响应的,所以虽然启动了其他线程,但是却是一个线程在执行,并不能算标准的多线程。
4、线程池
使用@aysnc注解实现多线程同一个类中,方法a 引用方法b 方法b加异步@async注解 不会有效
被加@async方法和调用方 不能再同一个类中
用户线程与守护线程的区别java内创建的线程默认是创建用户线程,比如new thread(线程对象).start
thread thread = new thread(); // 默认为false,都是用户线程 thread.setdaemon(true); // 表示设置为守护线程 thread.setdaemon(false); // 表示设置为用户线程
用户线程:不zhi随着其他线程的死亡而死亡,只有两种情况dao死掉,一是在运行中出现异常而终止,二是正常把程序执行完毕,线程死亡
守护线程:随着用户线程的死亡而死亡,当用户线程死完了守护线程也死了,比如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()方法在线程中,线程正在等待的是哪个锁就不明显了。
以上就是java多线程run方法中怎么直接调用service业务类的详细内容。
