Java多线程那些事(一)

Java多线程那些事(一)

大家好,我是栗子为。

” 很开心又和大家见面了,这两天朋友没和我吐槽面试,我突然失去了灵感,这让我怎么还原最真实的面试场景,给我的栗子们分享最真实的面试题,看来只能自己硬着头皮去回忆了,还是老规矩,一篇文章,让你掌握一个知识点。今天就聊聊Java中的多线程吧,这个话题算是面试中被问到最多的,难度适中,但内容还是挺多的,本次就先介绍面试中最常被问到的一些知识 “

话不多说,上干货…

先引入一个很经典的面试问题

线程和进程的区别?

进程是应用程序的执行实例,有独立的内存空间和系统资源

线程是CPU调度和分派的基本单位,进程中执行运算的最小单位,可完成一个独立的顺序控制流程

进程和线程的关系

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。

(3)处理机分给线程,即真正在处理机上运行的是线程。

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。



01


创建线程的方式



常用的创建线程有3种方式

继承Thread类

Thread类本质上是实现了Runnable接口的一个实例,通过调用Thread类的start()方法就可以启动线程

通常会继承Thread类,然后重写其run()方法

举🌰

public class ThreadDemo1 extends Thread {
public ThreadDemo1(String name) {
this.setName(name);
}

@Override
public void run() {
System.out.println("当前线程为:" + Thread.currentThread().getName());
}

public static void main(String[] args) throws Exception {
new ThreadDemo1("Thread1").start();
new ThreadDemo1("Thread2").start();
}
}

输出结果

当前线程为:Thread1
当前线程为:Thread2

实现Runnable接口

Java是单继承的,这种方式是为了解决当继承一个类后无法再继承Thread类,就可以通过实现Runnable接口的方式来实现多线程

首先实现Runnable接口,并重写run()方法,通过构造Thread实例,将Runnable实现类传入到Thread实例中,就可以实现多线程

举🌰

public class ThreadDemo2 implements Runnable {
@Override
public void run() {
System.out.println("当前线程为:" + Thread.currentThread().getName());
}

public static void main(String[] args) throws Exception {
ThreadDemo2 runnableImpl = new ThreadDemo2();
new Thread(runnableImpl, "Thread1").start();
new Thread(runnableImpl, "Thread2").start();
}
}

输出结果

当前线程为:Thread1
当前线程为:Thread2

实现Callable接口,利用FutureTask包装器来创建线程

可返回值的任务必须实现Callable接口

首先需要一个实现Callable接口的实例,然后用FutureTask来包装此实例,传递给Thread实例,启动线程。本质上也实现了Runnable接口

举🌰

public class ThreadDemo3 {
public static void main(String[] args) throws Exception {
// 创建线程任务,lambada方式实现接口并实现call方法
Callable<Integer> callable = () -> {
System.out.println("线程任务开始了...");
Thread.sleep(2000);
return 1;
};

// 将任务封装为FutureTask
FutureTask<Integer> task = new FutureTask<>(callable);

// 开启线程,执行线程任务
new Thread(task).start();

System.out.println("线程启动...");

Integer result = task.get();
System.out.println("main线程中拿到的结果为:" + result);
}
}

输出结果

线程启动...
线程任务开始了...
main线程中拿到的结果为:1

其实还有第四种,就是在开发中经常使用到线程池,这一部分内容比较多,我想单独拿出来作为下次分享,毕竟没有人能拒绝在吃饭的时候花5-6分钟看一道面试题吧,所以小为在写文章的时候,采用了分而治之的思想,希望一篇文章让大家毫无压力地掌握一个知识点,这就够啦!

我们继续继续….



02


线程的生命周期




Java多线程那些事(一)

只有就绪态(可运行/Runnable)和运行态(运行中/Running)可以相互转化。

初始状态(new)

实现Runnable接口或继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。

就绪状态(runnable)

  1. 就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。
  2. 调用线程的start()方法,此线程进入就绪状态。
  3. 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
  4. 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
  5. 锁池里的线程拿到对象锁后,进入就绪状态。

运行中状态(running)

线程调度程序从可运行池中选择一个线程使其进入到运行中状态。这也是线程进入运行状态的唯一的一种方式。

阻塞状态(blocked)

阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。

等待阻塞

通过调用线程的wait()方法,让线程等待某工作的完成。

同步阻塞

线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。

其他阻塞

通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

终止状态(dead)

当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。



03


Thread类常用的方法



  • start() : 启动当前线程, 调用当前线程的run()方法
  • run() : 通常需要重写Thread类中的此方法, 将创建的线程要执行的操作声明在此方法中
  • currentThread() : 静态方法, 返回当前代码执行的线程
  • getName() : 获取当前线程的名字
  • setName() : 设置当前线程的名字
  • yield() : 释放当前CPU的执行权
  • join() : 在线程a中调用线程b的join(), 此时线程a进入阻塞状态, 直到线程b完全执行完以后, 线程a才结束阻塞状态
  • stop() : 已过时. 当执行此方法时,强制结束当前线程.
  • sleep(long militime) : 让线程睡眠指定的毫秒数,在指定时间内,线程是阻塞状态
  • isAlive() :判断当前线程是否存活



04


总结



关于Java多线程,其实还有很多内容,常用的线程池、线程池的拒绝策略、线程同步、线程通信、线程死锁等等,后面和大家一一介绍,相信这个系列看完,你能和面试官battle300回合,离心仪offer越来越近,我们下期接着聊…

关注六只栗子,带你体验最真实的面试。

作者   栗子为   

编辑   一口栗子

原文始发于微信公众号(六只栗子):Java多线程那些事(一)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/88746.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!