1.请告诉我启动线程的三种方式
1:继承Thread类 2:实现Runnable 接口 3:Executors.newCachedThread();
2.多线程的关键字:Sleep:当前线程睡眠 Yieid:让出cpu一下返回线程就绪状态 Join:执行另外线程,等另外线程执行完了在执行当前线程
3.如何保证线程顺序执行? 使用 join关键字保顺序执行
4.线程的状态? 1:new(创建 ) 2 :runnable(read ---> running 两种状态 3 blocked( 阻塞状态) 4waiting( 等待) 5 timed_waiting(超时等待) 6 teminated( 线程完成)
5. Synchronized同步方法能和非同步方法一起调用吗?答案:可以
6.业务数据中 set 写方法添加同步锁,读方法 get不添加锁会造成脏读现象。
7.一个同步方法可以调用另外一个同步方法,一个线程拥有一个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是synchronized获得锁是可重入的。
8. Synchronized 方法如果产生了异常会释放锁。导致数据不一致.解决办法是catch处理
9. Synchronized(锁对象不是锁代码) 实现原理:锁升级:1markword记录线程id(偏向琐)如果线程争用,升级为自旋锁 自旋锁自旋10次以后升级为重量级锁 (也就是调用系统OS)
10.什么情况下使用自旋锁,什么情况下用重量级锁?
自旋锁(占用cpu
):执行时间短,线程少的话用自旋锁。
重量锁(不占用CPU)
执行时间长,线程多使用重量级锁
11.synchronized(object)不能用string常量integer,long 基本类型等数据类型。
12.小小面试题:好记性不如烂笔头。多敲敲代码!!!
package com.aia.thread;
import java.util.concurrent.TimeUnit;
/**
* 面试题:模拟银行账户
* 对业务写方法加锁
* 对业务读方法不加锁
* 会造成脏读现象出现
* @author My
*
*/
public class T3 {
String name;
double balance;
public synchronized void set(String name,double balance) {
this.name = name;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.balance = balance;
}
public synchronized double getBalance() {
return this.balance;
}
public static void main(String[] args) {
T3 t3 = new T3();
new Thread(()->t3.set("jason", 100.0)).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(t3.getBalance());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(t3.getBalance());
}
}