笔者福利
以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。
有了这个,面试踩雷?不存在的!
回馈粉丝,诚意满满!!!
//获取当前线程t1
//t2线程执行此方法,当前对象就是t2
Thread t=Thread.currentThread();
System.out.println(t.getName()+"线程----->"+i);//t1
try {
//休眠一秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
main
t1
t2
t2线程----->0
t1线程----->0
t2线程----->1
t1线程----->1
t2线程----->2
t1线程----->2
t2线程----->3
t1线程----->3
t2线程----->4
t1线程----->4
t2线程----->5
t1线程----->5
t2线程----->6
t1线程----->6
t2线程----->7
t1线程----->7
t2线程----->8
t1线程----->8
t2线程----->9
t1线程----->9
Process finished with exit code 0
[]( )2.实现 Runnable 接口
-----------------------------------------------------------------------------
其实 Thread 对象本身就实现了 Runnable 接口,但一般建议直接使用 Runnable 接口来写多线程程序,因为接口会比类带来更多的好处
示例代码(2):
public class ThreadText02 {
public static void main(String[] args) {
//创建线程
Thread t=new Thread(new MyRunnable());
//启动线程
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("主线程----->"+i);
}
}
}
class MyRunnable implements Runnable{
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("分支线程----->"+i);
}
}
}
运行结果:
主线程----->0
分支线程----->0
主线程----->1
分支线程----->1
主线程----->2
分支线程----->2
主线程----->3
分支线程----->3
主线程----->4
分支线程----->4
主线程----->5
分支线程----->5
主线程----->6
分支线程----->6
主线程----->7
分支线程----->7
分支线程----->8
分支线程----->9
主线程----->8
主线程----->9
[]( )3.实现线程的第三种方式实(现Callable接口。(JDK8新特性。))
--------------------------------------------------------------------------------------------------
这种方式实现的线程可以获取线程的返回值。(效率低)
示例代码:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;//JUC包下的,属于java并发包,老jdk没有,新特性
public class ThreadText14 {
public static void main(String[] args) {
FutureTask task=new FutureTask(new Callable() {
@Override
public Object call() throws Exception {//call方法相当于run方法,但是有返回值
System.out.println("call method begin");
Thread.sleep(1000*2);
int a=100;
int b=200;
return a+b;//(自动装箱)
}
});
Thread ti=new Thread(task);
//开始
ti.start();
//get方法导致当前线程阻塞!!
try {
Object obj=task.get();
System.out.println("线程执行结果--->"+obj);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("hello world");
}
}
运行结果:
call method begin
线程执行结果—>300
hello world
[]( )三、线程的生命周期
======================================================================
#### []( )线程的生命周期存在五个状态:新建、就绪、运行、阻塞、死亡
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200727160400148.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pwX2luc2lzdA==,size_16,color_FFFFFF,t_70)
**新建:采用 new语句创建完成
就绪:执行 start 后
运行:占用 CPU 时间
阻塞:执行了 wait 语句、执行了 sleep 语句和等待某个对象锁,等待输入的场合
终止:退出 run()方法**
[]( )四、多线程并发环境下,数据的安全问题。
================================================================================
* **什么时候数据在多线程并发的环境下会存在安全问题呢?**
三个条件:①多线程并发②有数据共享③共享数据有修改的行为。
* **怎么解决线程安全问题呢?**
使用线程同步机制:线程排队执行。(不能并发)
[]( )线程同步与线程异步的理解
-------------------------------------------------------------------------
异步编程模型:
线程t1和线程t2,各自执行各自的,t1不管t2,t2不管t1,
谁也不需要等谁,这种编程模型叫做:异步编程模型。
其实就是:多线程并发(效率较高。)
异步就是并发。
同步编程模型:
线程t1和线程t2,在线程t1执行的时候,必须等待t2线程执行
结束,或者说在t2线程执行的时候,必须等待t1线程执行结束,
两个线程之间发生了等待关系,这就是同步编程模型。
效率较低。线程排队执行。
同步就是排队。
#### []( )线程同步其实是对对象加锁(给对象加锁使用“synchronized”关键字:)
**synchronized有三种写法:**
①同步代码块
synchronized(线程共享对象){
同步代码块;
}
线程共享对象必须是多线程共享的数据。
java中,任何对象都有一把锁,是一个标记,让哪个线程排队,让那个线程共享数据
②在实例方法上使用synchronized表示共享对象一定是this并且同步代码块是整个方法体。
③在静态方法上使用synchronized表示找类锁。类锁永远只有1把。
**Java中三大变量:**
实例变量:在堆中。
静态变量:在方法区。
局部变量:在栈中。
> 以上三大变量中:
> 局部变量永远都不会存在线程安全问题。
> 因为局部变量不共享。(一个线程一个栈。)
> 局部变量在栈中。所以局部变量永远都不会共享。
实例变量在堆中,堆只有1个。
静态变量在方法区中,方法区只有1个。
堆和方法区都是多线程共享的,所以可能存在线程安全问题。
局部变量+常量:不会有线程安全问题。
成员变量:可能会有线程安全问题。
#### []( )以后开发中应该怎么解决线程安全问题?
1.尽量使用局部变量代替“实例变量和静态变量”。
2.如果必须是实例变量,那么可以考虑创建多个对象,这样实例变量的内存就不共享了。
3.如果不能使用局部变量,对象也不能创建多个,这个时候就只能选择synchronized了。线程同步机制。
#### []( )Java中怎样终止一个线程
使用布尔标记:
示例代码(3):
public class ThreadText10 {
public static void main(String[] args) {
MyRunnable4 r = new MyRunnable4();
Thread t = new Thread(r);
t.setName("t");
t.start();
try {
t.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//终止线程
//想要什么时候终止,把标记修改为false就终止!
r.run=false;
}
}
class MyRunnable4 implements Runnable {
//打一个布尔标记
Boolean run = true;
@Override
public void run() {
if (run) {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "---->" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
//在这里保存数据!!!
return;
}
}
}
[]( )为了预防死锁的出现,面试官说:“请手写一个死锁代码”。
----------------------------------------------------------------------------------------
示例代码(4):
public class ThreadText04 {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
Thread t1 = new MyThread01(o1, o2);
Thread t2 = new MyThread02(o1, o2);
t1.start();
t2.start();
}
}
class MyThread01 extends Thread {
Object o1;
Object o2;
public MyThread01(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
@Override
public void run() {
synchronized (o1){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
}
}
}
}
class MyThread02 extends Thread {
Object o1;
Object o2;
public MyThread02(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
public void run() {
synchronized (o2){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1){
}
}
}
}
[]( )五、守护线程
===================================================================
java语言中线程分为两大类:
一类是:用户线程
一类是:守护线程(后台线程)
其中具有代表性的就是:垃圾回收线程(守护线程)。
**守护线程:所有的用户线程结束生命周期,守护线程才会结束生命周期,只要有一个用户线程存在,那么守护线程就不会结束,例如 java 中著名的垃圾回收器就是一个守护线程,只有应用程序中所有的线程结束,它才会结束。**
**守护线程的特点:**
一般守护线程是一个死循环,所有的用户线程只要结束,
守护线程自动结束。
示例代码(5):
/*
守护线程!!
最后
光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性
Java面试宝典2021版
最常见Java面试题解析(2021最新版)
2021企业Java面试题精选
有一个用户线程存在,那么守护线程就不会结束,例如 java 中著名的垃圾回收器就是一个守护线程,只有应用程序中所有的线程结束,它才会结束。**
守护线程的特点:
一般守护线程是一个死循环,所有的用户线程只要结束,
守护线程自动结束。
示例代码(5):
/*
守护线程!!
### 最后
光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的**增加文章的篇幅**,减少文章的可读性
# Java面试宝典2021版
[外链图片转存中...(img-6NQT5MWq-1715150524696)]
[外链图片转存中...(img-7Q0Snmay-1715150524696)]
# 最常见Java面试题解析(2021最新版)
[外链图片转存中...(img-fJTJSWN1-1715150524697)]
[外链图片转存中...(img-2OQO7eoV-1715150524697)]
# 2021企业Java面试题精选
[外链图片转存中...(img-VDEa2SOx-1715150524697)]
[外链图片转存中...(img-cd8LRG7x-1715150524698)]
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**
**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**