当前位置: 首页 > news >正文

JAVA面试汇总(二)多线程(五)

JAVA多线程内容比较多,今天写完了第五篇,后边还有六。

  1. 对象锁和类锁是否会互相影响?
    (1)我前面讲过的,带有synchronized的static方法,必须单独执行,无论是多个实例操作,只要访问统一方法,都需要等待迁移执行完毕
    (2)但是当访问的是带synchronized的普通方法(对象锁),这种如果创建多个实例,互相是不干扰的,可以并行执行,但是同一个实例的情况下需要等待前一个执行完毕才能下个执行
    (3)多个实体同时有类锁以及对象锁时候,也是互补干扰的,类锁实际锁的是静态的同步方法,如果不调用同步方法,就不会影响,也就是各自锁各自的。
public class TwoSynchronized {public static synchronized void method1() {try {System.out.println(Thread.currentThread().getName() + " method1 started");Thread.sleep(500);System.out.println(Thread.currentThread().getName() + " method1 end");}catch (Exception e){}}public synchronized void method2() {try {System.out.println(Thread.currentThread().getName()+" method2 started");Thread.sleep(500);System.out.println(Thread.currentThread().getName()+" method2 end");}catch (Exception e){}}public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 10; i++) {TwoSynchronized one = new TwoSynchronized();new Thread(new Runnable() {@Overridepublic void run() {one.method1();}}).start();}for (int i = 0; i < 10; i++) {TwoSynchronized two = new TwoSynchronized();new Thread(new Runnable() {@Overridepublic void run() {two.method2();}}).start();}Thread.sleep(100000);}
}
//输出,可以看出method1和method2同时执行了
//说明了类锁存在的情况下,对象锁还可以同时执行
Thread-0 method1 started
Thread-10 method2 started
Thread-11 method2 started
Thread-14 method2 started
Thread-15 method2 started
Thread-18 method2 started
Thread-19 method2 started
Thread-12 method2 started
Thread-13 method2 started
Thread-16 method2 started
Thread-17 method2 started
Thread-13 method2 end
Thread-11 method2 end
Thread-0 method1 end
Thread-12 method2 end
Thread-14 method2 end
Thread-15 method2 end
Thread-18 method2 end
Thread-19 method2 end
Thread-16 method2 end
Thread-17 method2 end
Thread-9 method1 started
Thread-10 method2 end
Thread-9 method1 end
Thread-7 method1 started
Thread-7 method1 end
Thread-6 method1 started
Thread-6 method1 end
Thread-3 method1 started
Thread-3 method1 end
Thread-2 method1 started
Thread-2 method1 end
Thread-8 method1 started
Thread-8 method1 end
Thread-5 method1 started
Thread-5 method1 end
Thread-4 method1 started
Thread-4 method1 end
Thread-1 method1 started
Thread-1 method1 end
  1. Java中ConcurrentHashMap的并发度是什么?
    ConcurrentHashMap把实际map划分成若干部分来实现它的可扩展性和线程安全。这种划分是使用并发度获得的,它是ConcurrentHashMap类构造函数的一个可选参数,默认值为16。注意注意,这个仅限于JDK1.7,在JDK1.8不用分段了,用的CAS方式重试去写入,所以不存在并发度了。

  2. 什么是Java Timer类?如何创建一个有特定时间间隔的任务?
    (1)java.util.Timer 是一个工具类,可以用于安排一个线程在未来的某个特定时间执行。Timer类可以用安排一次性任务或者周期任务。
    (2)Timer有几个schedule方法,可以设定指定时间执行,或者指定间隔执行等操作。
    (3)schedule(TimerTask task, Date time),其中TimerTask表示需要执行的任务。

import java.util.Timer;
import java.util.TimerTask;public class TimerTest01 {public TimerTest01(int time){Timer timer = new Timer();timer.schedule(new TimerTaskTest01(), time * 1000);System.out.println(time * 1000);}public static void main(String[] args) {System.out.println("timer begin....");// 3秒后执行内部具体任务new TimerTest01(3);System.out.println("timer end....");}static class TimerTaskTest01 extends TimerTask {public void run() {// 执行的任务System.out.println("Time's up!!!!");}}
}
  1. SimpleDateFormat是线程安全的吗?
    (1)SimpleDateFormat底层实现是用的Calendar,其中parse时候调用了CalendarBuilder.establish()方法,
    (2)其中先后调用了cal.clear()与cal.set(),这样就把静态实体的值修改了,所以在多线程parse过程中导致了问题。
    (3)那么如何避免呢:需要使用局部变量,每个线程种,都单独创建SimpleDateFormat;
                    try {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH");System.out.println(simpleDateFormat.parse("2020-01-01 15"));} catch (ParseException e) {System.out.println("线程:" + Thread.currentThread().getName() + " 格式化日期失败");e.printStackTrace();System.exit(1);}

(4)另外一种为parse的前后,SimpleDateFormat对加锁

                    try {synchronized (simpleDateFormat){simpleDateFormat.parse("2020-01-01");}} catch (ParseException e) {System.out.println("线程:" + Thread.currentThread().getName() + " 格式化日期失败");e.printStackTrace();System.exit(1);}

(4)执行前加Lock.lock,执行完成后unlock
(5)通过ThreadLocal,每个线程独立的simpleDateFormat

//在线程run方法同级别创建threadlocalprivate static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){@Overrideprotected DateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd");}};
//run方法中实现,每个线程过来,通过threadLocal中取出来,但是这种和上面(3)每个线程创建独立的SimpleDateFormat没有区别吧?
//如果这条有异议可以给我评论,咱们再讨论try {threadLocal.get().parse("2020-01-01");} catch (ParseException e) {System.out.println("线程:" + Thread.currentThread().getName() + " 格式化日期失败");e.printStackTrace();System.exit(1);}
  1. 用Java写一个会导致死锁的程序,你将怎么解决?
    (1)两个线程分别都要锁定两个变量
    (2)两个线程分别都获取锁定了一个变量,各自不同
    (3)两个线程分别都等待对方释放另一个变量,结果谁也不会释放,就死锁了
public class TestDeadLock {public static void main(String[] args) {Object a = new Object();Object b = new Object();Thread runnableA = new Thread(new Runnable() {@Overridepublic void run() {synchronized (a){System.out.println("runnable a lock a");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("runnable a waiting b");synchronized (b){System.out.println("runnable a lock b");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}});Thread runnableB =  new Thread(new Runnable() {@Overridepublic void run() {synchronized (b){System.out.println("runnable b lock b");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("runnable b waiting a");synchronized (a){System.out.println("runnable b lock a");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}});runnableA.start();runnableB.start();}
}
//输出
runnable b lock b
runnable a lock a
runnable a waiting b
runnable b waiting a
//后边就一直互相等待了

(4)所以应该尽量避免多线程执行中,一个线程锁定多个
(5)如果必须要锁定多个,那么尽量要锁定顺序一致
(6)使用定时锁tryLock,一段时间以后timeout会释放锁

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;public class TestDeadLock {static ReentrantLock a = new ReentrantLock();static ReentrantLock b = new ReentrantLock();public static void main(String[] args) {Thread runnableA = new Thread(new Runnable() {@Overridepublic void run() {try {a.tryLock(10, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();System.out.println("runnable a lock a failed");return;}System.out.println("runnable a lock a");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("runnable a waiting b");try {b.tryLock(10, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();System.out.println("runnable a lock b failed");return;}System.out.println("runnable a lock b");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});Thread runnableB = new Thread(new Runnable() {@Overridepublic void run() {try {b.tryLock(5, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();System.out.println("runnable b lock b failed");return;}System.out.println("runnable b lock b");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("runnable b waiting a");try {a.tryLock(5, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();System.out.println("runnable b lock a failed");return;}System.out.println("runnable b lock a");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});runnableA.start();runnableB.start();}
}
//输出
runnable a lock a
runnable b lock b
runnable a waiting b
runnable b waiting a
runnable b lock a
runnable a lock b

谢各位的阅读,谢谢您动动手指点赞,万分感谢各位。另外以下是我之前写过的文章,感兴趣的可以点进去继续阅读。

历史文章

Hadoop系列-入门安装
Hadoop系列-HDFS命令
Hadoop系列-Hive安装
Hadoop系列-Hive数据库常见SQL命令
Hadoop系列-HBase数据库
Hadoop系列-HBase数据库(二)
Hadoop系列-HBase数据库JAVA篇
Hadoop系列-Spark安装以及HelloWorld
JAVA面试汇总(五)数据库(一)
JAVA面试汇总(五)数据库(二)
JAVA面试汇总(五)数据库(三)
JAVA面试汇总(四)JVM(一)
JAVA面试汇总(四)JVM(二)
JAVA面试汇总(四)JVM(三)
JAVA面试汇总(三)集合(一)
JAVA面试汇总(三)集合(二)
JAVA面试汇总(三)集合(三)
JAVA面试汇总(三)集合(四)
JAVA面试汇总(二)多线程(一)
JAVA面试汇总(二)多线程(二)
JAVA面试汇总(二)多线程(三)
JAVA面试汇总(二)多线程(四)
JAVA面试汇总(二)多线程(五)
JAVA面试汇总(二)多线程(六)
JAVA面试汇总(二)多线程(七)
JAVA面试汇总(一)Java基础知识

最后编辑于:2025-08-30 16:26:05


喜欢的朋友记得点赞、收藏、关注哦!!!

http://www.dtcms.com/a/528533.html

相关文章:

  • 怎样设计网站模板网站 建设初步
  • 网站建设所需的硬件设备网站运营工作是干什么的
  • 网站中的表格wordpress后台404
  • 从零开始:C++ 多进程 TCP 服务器实战(续篇)
  • 阮一峰《TypeScript 教程》学习笔记——装饰器
  • 一、基础预训练模型与能力
  • 上海网站建设选缘魁-企查公司简介模板文案
  • 重磅新书 | 《链改2.0:从数字资产到RWA》
  • 【IOS开发】SwiftUI + OpenCV实现图片的简单处理(一)
  • 【Docker】docker run
  • 成都网站建设 Vr便民网
  • LLama3架构原理浅浅学学
  • docker存储管理
  • Transformer架构发展历史
  • 【AI原生架构:数据架构】9、从打破数据孤岛到价值升维,企业数据资产变现全流程
  • Kubernetes 上的 GitLab + ArgoCD 实践(二):使用自建 GitLab Runner 完善 CI 流程
  • 网站如何查看浏览量2008建设网站
  • 开学季技术指南:高效知识梳理与实战经验分享
  • 网站推广计划渠道国外做美食视频网站有哪些
  • 金蝶K3老单 工艺路线维护特殊字符(使用模块返回值的方法)
  • 信贷控制范围
  • 乐陵网站优化最简单的网站设计
  • 项目信息和生产安全管理指南(试行)
  • 【Tesla】ICCV 2025技术分享
  • 企业做网站营销企业网站 响应式
  • 深度学习C++中的数据结构:栈和队列
  • 2025-tomcat web实践
  • 免费建立微信网站如何设计的英文网站
  • liferay 做网站哪里有网站开发公司
  • Leetcode 38