java线程(网易大数据面试题)
Posted somelovelanguage
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java线程(网易大数据面试题)相关的知识,希望对你有一定的参考价值。
网易大数据面试题目
- 线程的实现方式有什么,写出来
- 讲一下synchronize和volatile锁的问题
一、线程的实现方式
1.继承Thread类(创建Thread类的匿名子类)
- 自定义类继承Thread类
- 重写run方法
- new一个自定义类,调用start方法
//1. 继承类的方式创建线程,数据未共享
Thread atm1 = new ATM();
Thread atm2 = new ATM();
atm2.start();
atm1.start();
class ATM extends Thread{
private int money = 100;
@Override
public void run() {
while (money>=0){
System.out.println(Thread.currentThread().getName()+"-继承Thread类的atm:"+money--);
}
}
}
2.实现Runnable接口
- 自定义类实现Runnable接口
- 实现run方法
- new一个自定义类,作为参数传递到Thread类构造器中,new一个Thread类
- 调用Thread类的start方法
两种方式对比
- 优先选用Runnable,不需继承,避免了继承一个类的局限性
- 适合处理共享数据(不是说继承类不能处理共享数据,用代理类(单例模式+代理)也可以轻松处理共享数据)
//2. 实现Runnable接口的方式创建线程,数据共享
ATM1 atm3 = new ATM1();
Thread thread1 = new Thread(atm3);
Thread thread2 = new Thread(atm3);
thread1.start();
thread2.start();
class ATM1 implements Runnable{
private int money = 100;
@Override
public void run() {
while (money>0){
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
synchronized (this){
System.out.println(Thread.currentThread().getName()+"-实现接口的atm:"+money--);
}
}
}
}
3.实现Callable接口
- 实现Callable接口,重写call方法
- new一个自定义类,作为参数传入FutureTask类构造器,new一个FutureTask对象
- FutureTask对象作为参数传入Thread类构造器,new一个Thread对象
- 调用start方法
//3. 实现Callable接口的方式创建线程
ATM2 atm2 = new ATM2();
FutureTask futureTask = new FutureTask<>(atm2);
Thread thread = new Thread(futureTask);
thread.start();
class ATM2 implements Callable{
private int money = 100;
@Override
public Object call() {
while (money>=0){
System.out.println(Thread.currentThread().getName()+"-实现Callable接口的atm:"+money--);
}
return null;
}
}
4.线程池创建线程
- Executors类创建一个线程池对象
- 设定线程池属性
- 调用线程池的submit方法(含run的对象)或commit方法(含call的对象),
- 关闭线程池
// 4. 线程池创建线程
// 创建一个线程池
ExecutorService service = Executors.newFixedThreadPool(10);
//设置线程池的属性
ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
service1.setCorePoolSize(15);
service.execute(new ATM());//适合用于Runnable和继承Thread类
// service.submit();//适合用于Callable
service.shutdown();
Thread类常用方法
currentThread:静态方法,返回当前执行代码的线程(Thread类的对象)
setName():为线程设定名字
getName():获取当前线程名字
start(): 启动线程
sleep(): 静态方法,让当前线程沉睡 毫秒
yield()释放当前cpu的执行权
join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到b完全执行后,a才结束阻塞状态
二、线程的同步
1.synchronized
- 同步代码块 synchronized(同步监视器){}
- 同步方法(方法中只包含处理共享数据的代码)
- 同步监视器,俗称锁,多个线程必须共用一把锁,任何一个类的对象都可以充当锁。
- 同步方法,仍需同步监视器,只是未显式声明。
- 非静态的同步方法,同步监视器是this
- 静态的同步方法,同步监视器是:当前类本身(为Class的对象)
2、lock锁
- 新建一个lock锁
- 读写共享数据之前调用lock方法
- 结束时调用unlock方法,注意多个线程用同一把锁。
//lock锁
ATM3 atm3 = new ATM3();
ProxyThread proxyThread1 = new ProxyThread(atm3);
ProxyThread proxyThread2 = new ProxyThread(atm3);
ProxyThread proxyThread3 = new ProxyThread(atm3);
proxyThread1.start();
proxyThread2.start();
proxyThread3.start();
class ATM3 {
private int money = 100;
private Lock lock = new ReentrantLock();
public void modMoney() throws InterruptedException {
// Thread.sleep(1000);
while (true){
lock.lock();
if(money>=0)
System.out.println(Thread.currentThread().getName()+"-继承Thread类的atm:"+money--);
lock.unlock();
}
}
}
class ProxyThread extends Thread{
private ATM3 atm ;
ProxyThread(ATM3 atm){
this.atm = atm;
}
@Override
public void run() {
try {
atm.modMoney();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
三、线程的调度
- 调度策略
-
时间片
-
抢占式:高优先级的线程抢占cpu
- java的调度方法
- 同优先级线程组成先进先出队列,使用时间片策略
- 对高优先级,使用优先调度的抢占式策略
线程的优先级
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5 --默认优先级
获取和设置线程优先级
1. getPriority 获取线程优先级
2. setPriority设置线程优先级
高优先级的线程要抢占低优先级线程cpu的执行权,但只是从概率上讲,并不意味着只有当高优先级的线程执行完后,低优先级的线程才执行
四、线程的生命周期
JDK用Thread.State类定义了线程的几种状态
新建、就绪、阻塞、运行、死亡
五、线程通信
- wait() 使调用线程进入阻塞状态,并释放锁(与sleep不同)
- notify() 唤醒一个含有wait()的线程(优先级最高的),
- notifyAll():唤醒所有含有wait()的线程
说明:
- 上述三个方法必须使用在同步代码块或同步方法中(lock不行)
- 这三个方法的调用者必须是同步代码块或同步方法中的同步监视器,否则出现异常
- 上述三个方法定义在java.lang.Object类中
sleep()和wait()的异同
1. 相同点:一旦执行方法,都可以使得当前线程进入阻塞状态
2. 不同点:
1. 两个方法声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
2. 调用的要求不同:sleep()可以在任何需要的场景下调用。wait()必须使用在同步代码块中
3. 关于是否释放同步监视器:sleep()不释放,wait()释放
六、未学到 :volatile(改日再更)
以上是关于java线程(网易大数据面试题)的主要内容,如果未能解决你的问题,请参考以下文章