java多线程的使用
1. 并行和并发的区别:并行是多个事件在同一时刻发生,并发是多个事件在同一时间段发生;并行是不同的线程做不同的事,并发是不同的线程做相同的事。单核中不存在并行。
2. 线程和进程的区别:进程是操作系统资源分配的基本单位,线程是任务执行的基本单位;进程之间资源不共享,同一进程下的多个线程资源共享;
3. 守护线程:就是服务于其他线程,当其他线程执行完成后,jvm停止,守护线程也结束;在守护线程中产生的新线程也是守护线程。比如垃圾回收线程。不是守护线程的都属于用户线程,根据具体的业务逻辑执行完成后停止。通过thread的setDaemon(true)方法设定当前线程为守护线程;该方法要在start()之前设定。守护线程伴随着线程启动开始,直到进程结束。如下代码测试:
public Object run(){
new Thread(() -> {
for (int i = 0; i < 30; i++)
System.out.println(i);
}).start();
Thread thread = new Thread(() -> {
while (true) {
try{
Thread.sleep(100);
} catch (Exception e){
e.printStackTrace();
}
System.out.println("守护线程在在执行");
}
}
);
thread.setDaemon(true);
thread.start();
return "success";
}
4. 创建线程的几种方式:继承thread类,实现runnable接口。还有使用上述的函数式编程。
5. runnable和callable:两者都可以实现多线程,都使用Thread.start()方法启动;callable可以返回结果,并且抛出异常,线程池执行只能使用submit(),通过返回future的get方法获取定义的泛型返回值,future.cancel可以取消执行。runnable只能在内部处理异常,线程池执行可以使用submit()和execute(),通过返回future的get方法返回null。
6. 线程状态:创建,就绪,运行,阻塞,死亡。new Thread后进入创建状态;调用start进入就绪状态,等待和睡眠完成后也进入就绪状态;线程调度将就绪状态线程设置为当前线程,变为正在运行状态;运行过程中被暂停进入阻塞状态,sleep和suspend会使线程进入阻塞状态;线程中方法运行完成后进入死亡状态。
7.sleep和wait的区别:sleep是thread的方法,wait是object中的方法。sleep可以在任意地方使用,wait只能在同步方法或者同步块中使用。两者都会暂停当前线程,并让出cpu时间,但sleep不会释放当前持有的对象锁,到时间继续执行,而wait方法会释放所有的锁,等待notify或者notifyAll方法唤醒,重新获取锁。
扩展:wait为什么要加在同步块:由于wait要释放所有的锁,所以调用方法之前必须保证获得当前对象的锁。而且不加锁,不是当前对象的持有者,不能调用该方法。
8. notify和notifyAll:notify只随机唤醒一个线程,notifyAll唤醒所有等待的线程。如果当前没有线程存在等待队列中,这两个方法不起作用。
9. run和start:start是启动线程,run是Thread中的普通方法还是在主线程中按顺序执行。
10. 线程停止的方式:stop比较暴力,可能导致一些清理性的工作未完成(不推荐);interrupt在当前线程中增加中断标记,不会马上停止,isInterrupted方法判断线程是否停止,interrupted方法Thread中的静态方法,判断当前线程是否停止,会改变状态。
11. yield方法将当前运行状态线程变成就绪状态。
12.通过getState获取当前线程运行状态。
13.死锁:线程a持有锁l1,请求锁l2,线程b持有锁l2,请求锁l1,就进入死锁状态。避免死锁的方式,就是想办法让锁无法形成闭环,比如a和b进行操作时,都先申请l1锁,再申请l2锁。
14.多线程运行过程中怎么保证线程安全:使用synchronized对共享资源加上同步锁。
15.synchronized和volatile:synchronized强调执行过程中阻塞其他执行该模块的线程,volatile表示当前线程中变量不是最新值,需要去主存拿数据,不会造成阻塞。
扩展:线程运行过程中会将主存中的数据存放到线程内存中处理,线程执行完成后,将线程内存数据刷新到主存;synchronized作用在static方法上,锁住整个类。
16. lock和synchronized :synchronized使用方便,由jvm堆栈跟踪,加锁解锁由jvm控制,使用排他锁;lock提供读写锁,可定时,轮询获得锁,释放锁需要使用unlock,不适合jvm堆栈跟踪,由java实现。
17. reentrantlock和synchronized:reentrantlock提供了多种锁方式,在资源竞争不激烈的情况下synchronized性能好,竞争激烈的情况下reentrantlock性能好。
18. ThreadLocal:设置一个线程本地变量;每启动一个线程就将ThreadLocal对象存到map中。适用于不需要共享资源的情况。
18. atomic原理:通过cas实现
19.synchronized的原理:暂时不理解,以后补充
20. 多线程锁升级:这是对synchronized做的一个优化,根据具体情况决定锁的强度,从而提高性能。偏向锁,轻量级锁,重量级锁,前两个是乐观锁,最后一个是悲观锁;轻量级锁与偏向锁的不同之处在于,轻量级锁每次使用cas同步获取对象,偏向锁直接获取对象;轻量级锁获取对象失败时;判断对象头存储是否指向当前线程的指针,如果是获取对象,如果不是,升级为重量级锁。
10万+

被折叠的 条评论
为什么被折叠?



