java 高级面试系列 (三)----JUC (java 并发编程)

1,面试官: 什么是线程,什么进程 ? 

 小菜弱弱的回答: 大学操作系统书上说: 进程是操作系统的基本单位, 多个线程组成进程,即一个进程包含多个线程;比如 播放网易云这个进程服务,同时执行播放音乐服务线程,还能提供收集喜欢歌曲的统计线程等等;

追问: 什么是并发、并行?

 并发: 单核cpu ,模拟多个线程,交替执行,

并行: 多个cpu, 多个线程可以同时执行;

2, 面试官 : 线程分为哪几种状态?(源码中,enum.state )

小菜:1,  new thread 创建状态(线程刚被创建,‌但尚未启动 ),

       2 , runing(包括Running和Ready状态,‌表示线程正在运行或等待系统资源,‌如CPU时间片。‌)运行状态。

       3, 阻塞状态(‌BLOCKED)‌:‌线程因等待获取锁(‌synchronized关键字修饰的方法或代码块)‌而阻塞。‌

      4,waiting 等待状态线程等待被唤醒,‌否则将无限期等待。‌

      5, 超时等待(‌TIMED_WAITING)‌:‌线程等待被唤醒,‌但有一个超时时间,‌如使用sleep方法指定的时间到了后,‌线程会自动醒来。‌

      6, TERMINATED() 停止状态 线程的run()方法执行完毕或出现异常,‌线程结束其生命周期。‌

追问, sleep, wait 区别?

1, wait 是object 

sleep  thread;

2, sleep 抱着锁头睡,不释放锁,,wait 释放锁;

3, 使用范围不同;wait 用在同步代码块中,sleep 任何地方(并需要捕获异常);

3, 面试官:(我难为他),进程可以分为以下几种状:?

  1. 运行状态(‌Running)‌:‌进程正在占用处理器资源并执行。‌
  2. 就绪状态(‌Ready)‌:‌进程已经获得了除处理器之外的所有必要资源,‌等待系统分配处理器资源以便执行。‌
  3. 等待状态(‌Blocked)‌:‌进程因为等待某些事件(‌如I/O操作完成)‌而暂停运行,‌直到这些事件完成才能继续执行。‌

 4, 面试官: 什么是 juc ?

 小菜: java.util.*  并发编程包   其中lock、  callable 接口创建线程;

5, 面试官追问: java 常见线程有哪几种方式? 

小菜: new thread() , runnable 、 callable  ,还有线程池。。。。。

6,继续追问:创建线程池有哪几种方式? 

小菜:其实这里小菜不用等他问,可以自己根据上边回答到线程池就接着说,

 线程池的集中方式:

  1 ,  newSingleTHreadExecutor();  创建一个线程池

2, new FixedthreadExecutor(int num);  创建固定大小的数量的线程池

3, new cachedThreadExecutor(); 创建可变大小的线程池数量;

以上的阿里规约中, 不允许使用,使用下边的new ThreadExecutor () 创建;

  他的源码中,都是重写了ThreadExecutor

(int corePoolsize,   // 核心线程池大小 (代码中, CPU 密集型:Runtime.getRuntime().availableProcessors(), 获取代码中核数, IO密集型,就是判断程序中,十分耗费IO的线程数,可以 设置为他的2倍!!

int maxiumPoolSize, // z最大和线程池大小

long keepAliveTime,   //超时后无人调用释放

TimeUnit unit,  // 超时单位

BlockingQueue<Runable> workQueque,  // 阻塞队列

ThreadFactory threadFactory,   // 线程工厂, 创建线程,一办不动

RejectcecutionHandle handler)  // 拒绝策略

面试官: 四种决绝策略?

1,  abortpolicy() ,队列满了, 直接忽略,抛出异常;

2,callerRunspolicy (),哪里来的去哪里;(从哪个线程来,回到那个线程执行)

3, discardpolicy() 队列满了,丢掉任务,不会抛出异常

4,discardOldestPolicy() // 队列满了,尝试和最早的竞争,也

不会报异常

   

 面试官: java 真的能创建线程么?

小菜: 这是在问我 java 底层,java 不能创建线程,打开源码 new thread() 点击去,java 调用了 priate natice void start0();  底层调用 c++ 方法,通过本地方法栈,调用本地方法api 创建线程。

 synchronized 和 lock 区别?

1,synchornized 是 内置java 关键字,lock 是类;

2,lock 可以获取是否锁,sync 不能

3,sync自动释放,lock 手动释放;

4, sync 锁对象 方法同步代码块,lock 适合锁大量同步代码块

 手写一个jUC 生产者消费者?

public class HelloWorld {
    
 
    public static void main(String []args) {
       System.out.println("Hello World");
Data data = new Data();
		new Thread( ()-> {data.increment();}, "A").start();
		new Thread( ()-> {data.decrement();}, "B").start();
    }
	
	
	class Data {
	private int num = 0;
Lock lock = new  ReentranLock();
Condition con = lock.newCondidtion();
	// JUC 生产者 +1
	public  void increment() {
lock = lock();
   try() {
		if(num != 0) {
		   con.await();
		}
		num++;
		System.out.print("a==" + num);
		 con.await();
} catch () {} 
finally{
 lock.unlock();
  }
	}
	
	// 消费者 -1
	public  void decrement() {
lock = lock();
try() {
		if(num == 0) {
		    con.await();
		}
		num--;
		System.out.print("b==" + num);
		 con.await();
	}
} catch () {} 
finally{
 lock.unlock();
  }
	
	}
	
}

JUC 三个辅助类: 

countdownLatch 计数器, cycilc Barrirer  变量达到一定条件, 触发函数

semaphere 限流,原理: acqure() ; 获取到,假设已经满了,等待被释放,

 release() 释放,会将当前的信号量释放+1,然后唤醒等待的线程;

JUC 阻塞队列 blockingQueue  分为arrayBlockingQueue,和 LinkBlockingQueue;

   1, 同步队列 syncronousQueue  put 一个元素,必须take 取出;

JMM: 是什么?

1, java 内存模型,是个约定 : 1, mesi总线探嗅机制,线程解锁

前,必须把共享变量刷回驻存,

volatitel  : 1,保证可见性,2 不保证一致性;

  3,禁止指令重排

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值