记录一下滴滴二面没有答上来的两个题目
问题一:线程池如何知道线程的状态
这个问题我不知道是不是应该答线程的五种状态
并发编程:java线程池的五个状态_芳的程序员的博客-CSDN博客_java 线程池状态
问题二:synchronize修饰静态方法和非静态方法的区别
修饰静态方法,锁是加在类上的,类的所有对象竞争一把锁;修饰非静态方法,锁加在单个对象上,不同对象间没有竞争关系。
synchronized修饰静态方法和非静态方法 - 简书
首先,在java中,类只能被加载一次,引用会有多个。
然后,静态方法是不属于引用的,是属于这个类的。
synchronized如果修饰方法,jvm实现上其实是把所有的代码块用synchronized包裹住了。
synchronized(this){
//业务逻辑
}
如果是修饰静态方法,这个this就不是引用了,就是类了。
如果是修饰普通方法的话,这个this就是这个类的引用。
https://www.baidu.com/link?url=2eRXCZP6LaSNArmclltMoim4nPuz88fGnCP8zbdt3YE3BUC03xWi2qfOL2GR20F8sGOokX58_99iSlDylpZB9a&wd=&eqid=bfec08b00000ffdd0000000362b037d5
来做一个实验吧
public class Solutionaaa {
public synchronized static void sayhello(){
for(int i=0; i<100; i++) {
System.out.println("hello...");
}
}
public synchronized void sayhi(){
for(int i=0; i<100; i++) {
System.out.println(Thread.currentThread().getName() + " -> hi...");
}
}
public static void main(String[] args) {
Solutionaaa solutionaaa1 = new Solutionaaa();
Solutionaaa solutionaaa2 = new Solutionaaa();
new Thread(new Runnable() {
@Override
public void run() {
solutionaaa1.sayhi();
}
}, "Thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
solutionaaa2.sayhi();
}
}, "Thread2").start();
}
}
可以看到synchronized修饰非静态方法且使用不同实例执行该方法的时候是线程非安全的
将代码修改一下,使用同一个实例执行该方法
public class Solutionaaa {
public synchronized static void sayhello(){
for(int i=0; i<100; i++) {
System.out.println("hello...");
}
}
public synchronized void sayhi(){
for(int i=0; i<100; i++) {
System.out.println(Thread.currentThread().getName() + " -> hi...");
}
}
public static void main(String[] args) {
Solutionaaa solutionaaa1 = new Solutionaaa();
new Thread(new Runnable() {
@Override
public void run() {
solutionaaa1.sayhi();
}
}, "Thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
solutionaaa1.sayhi();
}
}, "Thread2").start();
}
}
可以发现使用synchronized修饰非静态方法且使用同一个实例执行该方法的时候是线程安全的
我们再来看一下修饰静态方法的情况
public class Solutionaaa {
public synchronized static void sayhello(){
for(int i=0; i<5; i++) {
System.out.println(Thread.currentThread().getName() + " -> hello...");
}
}
public synchronized void sayhi(){
for(int i=0; i<5; i++) {
System.out.println(Thread.currentThread().getName() + " -> hi...");
}
}
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
sayhello();
}
}, "Thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
sayhello();
}
}, "Thread2").start();
}
}
我执行了很多次,结果都是有序的,所以synchronized修饰静态方法的时候是线程安全的
那么我们小结一下
使用synchronized修饰静态方法时是线程安全的
使用synchronized修饰非静态方法且使用同一实例执行方法时是线程安全的
使用synchronized修饰非静态方法且使用不同实例执行方法时是线程不安全的
最后再说一下二面的时候算法题,一共是做了两道题。第一道是自己实现一下栈,写出入栈和出站的方法;第二道是二分查找,都不是很难。