java入门多线程一文通
创始人
2025-05-28 16:41:29
0

一、面试经典

1.为什么使用多线程及其重要

为了使用户体验更好,服务的相应速度更快。现如今硬件不断发展,软件要求也逐渐提高,都是为了一个字:快。

2.进程、线程、管程(monitor 监视器)

3.多线程并行和并发的区别

①并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行(需要多核CPU)
②并发是指两个任务都请求运行,而处理器只能接收一个任务,就是把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行(秒杀系统)

4.wait和sleep的区别?

wait是Object类中的方法,表示释放该线程执行权,需用Object中的notify|notifyAll唤醒。而sleep只是“阻塞”当前线程指定时间,不释放执行权,是Thread类中的方法。

5.synchronized和lock的区别?

(1). 原始构成a. synchronized是关键字属于JVM层面monitor对象,每个java对象都自带了一个monitor,需要拿到monitor对象才能做事情monitorenter(底层是通过monitor对象来完成,其实wait/notify等方法也依赖monitor对象,只能在同步块或方法中才能调用wait/notify等方法),进入monitorexit:退出b. lock是api层面的锁,主要使用ReentrantLock实现
(2). 使用方法a. synchronized不需要用户手动释放锁,当synchronized代码完成后系统会自动让线程释放
对锁的占用b. ReentrantLock则需要用户手动释放锁若没有主动释放锁,就有可能会导致死锁的现象
(3). 等待是否可中断?a. synchronized不可中断,除非抛出异常或者正常运行完成b. ReentrantLock可中断(设置超时时间tryLock(long timeout,TimeUnit unit),调用interrupt方法中断)
(4). 加锁是否公平a. synchronized非公平锁b. ReentrantLock两者都可以,默认是非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁
(5). 锁绑定多个Conditiona.synchronized没有b.ReentrantLock用来实现分组唤醒需要唤醒线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个\要么多个

6.多线程的实现方式

①基础Tread类

public class ThreadDemo {public static void main(String[] args) {MyThread myThread = new MyThread();myThread.start();for (int i = 0; i < 100; i++) {System.out.println("我是线程"+Thread.currentThread().getName()+"输出功能:"+i);}}
}class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("我是线程"+Thread.currentThread().getName()+"输出功能:"+i);}}
}

②实现Runnable接口

public class RunnableDemo {public static void main(String[] args) {MyThreadRunnable myThreadRunnable = new MyThreadRunnable();Thread t = new Thread(myThreadRunnable);t.start();for (int i = 0; i < 100; i++) {System.out.println("我是线程"+Thread.currentThread().getName()+"输出功能:"+i);}}}class MyThreadRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("我是线程"+Thread.currentThread().getName()+"输出功能:"+i);}}
}

两种实现多线程方式的区别

	(1).查看源码a.继承Thread:由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法b.实现Runnable:构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空编译时看的是Runnable的run(),运行时执行的是子类的run()方法(2).继承Threada.好处是:可以直接使用Thread类中的方法,代码简单b.弊端是:如果已经有了父类,就不能用这种方法(3).实现Runnable接口a.好处是:即使自己定义的线程类有了父类也没有关系,因为有了父类可以实现接口,而且接口
可以多现实的b.弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,
代码复杂

③Callable接口

(1)Callable接口中的call方法和Runnable接口中的run方法的区别

  • 是否有返回值(Runnable接口没有返回值 Callable接口有返回值)
  • 是否抛异常(Runnable接口不会抛出异常 Callable接口会抛出异常)

(2)Future接口概述

  • FutureTask是Future接口的唯一的实现类
  • FutureTask同时实现了Runnable、Future接口。它既可以作为Runnable被线程执行,又可以作为Futrue得到Callable的返回值
public class ThreadCallDemo {public static void main(String[] args) {CallThread callThread = new CallThread();FutureTask futureTask = new FutureTask(callThread);new Thread(futureTask).start();try {Object sum = futureTask.get();System.out.println(sum);} catch (Exception e) {e.printStackTrace();}}
}class CallThread implements Callable{@Overridepublic Object call() throws Exception {int sum = 0;for (int i = 0; i < 100; i++) {System.out.println(i);sum += i;}return sum;}
}

(3) 注意

  • get( )方法建议放在最后一行,防止线程阻塞(一旦调用了get( )方法,不管是否计算完成都会阻塞)
  • 一个FutureTask,多个线程调用call( )方法只会调用一次
  • 如果需要调用call方法多次,则需要多个FutureTask

④线程池

此文不做记录,见后续学习笔记。

二、线程基本设置

1.设置线程名

  • void setName(String name):将此线程的名称更改为等于参数 name
  • String getName( ):返回此线程的名称
  • 通过构造函数设置线程名称:
    -Thread(String name):通过带参构造进行赋值/Thread(Runnable target , String name)
  • static Thread currentThread​( )返回对当前正在执行的线程对象的引用
  • 注意:要是类没有继承Thread,不能直接使用getName( ) ;要是没有继承Thread,要通过Thread.currentThread得到当前线程,然后调用getName( )方法
      //FileWriterMyThread my1 = new MyThread();MyThread my2 = new MyThread();//void setName(String name):将此线程的名称更改为等于参数 namemy1.setName("线程1");my2.setName("线程2");my1.start();my2.start();

2.线程优先级(setPriority)

线程有两种调度模型:

  • 分时调度模式:所有线程轮流使用CPU的使用权,平均分配每个线程占有CPU的时间片
  • 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些 [ Java使用的是抢占式调度模型 ]

Thread类中设置和获取线程优先级的方法

  • public final void setPriority(int newPriority):更改此线程的优先级
  • public final int getPriority():返回此线程的优先级
  • a. 线程默认优先级是5;线程优先级范围是:1-10; b. 线程优先级高仅仅表示线程获取的CPU时间的几率高,但是要在次数比较多,或者多次运行的时候才能看到你想要的效果
    例子:下面不一定是线程2先执行,只是先执行得
      ThreadPriority tp1 = new ThreadPriority();ThreadPriority tp2 = new ThreadPriority();ThreadPriority tp3 = new ThreadPriority();tp1.setName("线程1");tp2.setName("线程2");tp3.setName("线程3");//设置正确的优先级tp1.setPriority(5);tp2.setPriority(10);tp3.setPriority(1);tp1.start();tp2.start();tp3.start();

3.线程控制(sleep、join、setDeamon)

①static void sleep(long millis):使当前正在执行的线程停留(暂停执行)指定的毫秒数 (休眠线程)

② void join():当前线程暂停,等待指定的线程执行结束后,当前线程再继续 (相当于插队加入)

③void join(int millis):可以等待指定的毫秒之后继续 (相当于插队,有固定的时间)

④void yield():让出cpu的执行权(礼让线程)

⑤void setDaemon​(boolean on):将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出(守护线程)(相当于象棋中的帅,要是帅没了,别的棋子都会没用了)

说明:

  • 守护线程是区别于用户线程哈,用户线程即我们手动创建的线程,而守护线程是程序运行的时候在后台提供一种通用服务的线程。垃圾回收线程就是典型的守护线程
  • 守护线程拥有自动结束自己生命周期的特性,非守护线程却没有。如果垃圾回收线程是非守护线程,当JVM 要退出时,由于垃圾回收线程还在运行着,导致程序无法退出,这就很尴尬。这就是为什么垃圾回收线程需要是守护线程
  • t1.setDaemon(true)一定要在start( )方法之前使用

在这里插入图片描述

相关内容

热门资讯

年轻人养生以食为补古法健身对抗... 养生人群逐渐年轻化,社交平台上,“养生食谱、中医养生、节气养生”等话题讨论踊跃。当代年轻人将“以食为...
美食遍地开花的沙坪坝,哪一道藏... 沙坪坝的滋味 是匠人掌心的老茧 是游子背包里的乡愁 是山城用百年光阴写给世界的烟火情书 // 此地烟...
原创 越... 朋友们,今天咱来唠唠一个挺有意思的事儿,你们有没有好奇过,越南美女口中常提到的生菜,到底有啥特别意思...
四川成都:乐游都江堰 成都乐游... 来源:人民网-图片频道2025年6月9日,游客在四川成都都江堰景区游玩参观。黄胜林摄(人民图片网)
原创 炖... #炖菜入酒,醇香翻倍,过节最全调味小窍门都在这,一分钟了解透彻 在节日的欢聚时刻,一锅热气腾腾、香...
原创 上... 下班回到家累成狗,还要花一小时做饭?外卖都吃腻了又怕不健康?别担心!今天教你几道闪电速度的快手晚餐,...
藏在记忆中的味道 (图片由AI生成) ■冯燮 一大早,儿子在出门前说道:“爸,难得周末有空,我好想吃你做的红烧肉。”...
原创 酱... 街头小摊的酱香饼,香到隔壁小孩都馋哭了 还记得街角那个酱香饼小摊吗?早上路过,香气扑鼻,饼皮金黄酥脆...
原创 北... 在中国美食的江湖里,北方人把面食玩出了花。从宫廷御膳到街头小摊,那些历经百年沉淀的手艺,如今成了舌尖...
潮汕5天跟团游怎么选?2025... 潮汕地区,这片充满烟火气与文化底蕴的土地,一直是我心心念念的旅行目的地。它不仅有着独特的文化传统,还...
高考后“家庭游”爆火!昆明位列... 6月10日,同程旅行发布《2025高考毕业热门旅游指南》(以下简称:《指南》)显示,高考结束到志愿填...
原创 炒... #炒猪肉时,什么时候放酱油?之前没注意,难怪肉不鲜 在烹饪的奇妙世界里,炒猪肉这道家常菜看似简单,...
原创 无... #无论炖什么鱼,下锅前还需多加这一步,否则鱼肉不入味还发腥 在烹饪的奇妙世界里,炖鱼是一道能让人品...
原创 炖... #炖羊肉别只会用花椒和大葱了,试试用“它”炖,羊肉软烂没膻腥味 在美食的世界里,炖羊肉是一道令人垂...
从成都出发坐飞机1个多小时到荆... 飞机落地荆州时刚过下午3点,我拖着行李箱打车到沙市区红星路附近的酒店,想着第2天早上直奔小龙锅回民早...
四川九寨沟峨眉山旅游跟团5天4... 四川,一个让人魂牵梦绕的地方。这里不仅有麻辣鲜香的美食,还有丰富的自然景观和深厚的历史文化。从巍峨的...
四川旅游自驾游5天要多少钱,驴... 作为一枚热爱旅行的驴友,我一直对四川这片“天府之国”充满了无限向往。从熊猫基地的憨态可掬,到九寨沟的...
北京旅游四天三晚旅游行程,北京... 北京旅游四天三晚旅游行程,北京4日旅游必玩的景点有那些? 北京,这座承载着厚重历史的千年古都,是中...
西安五日游旅游行程,西安纯玩行... 西安,这座承载着千年历史的古都,以其丰富的文化遗产、壮丽的古迹风光和诱人的美食文化,成为了无数旅行者...