1.线程创建的四种方式?
ExecuteService es=Executor.newCachedThreadPool();然后可以通过实现Runnable接口和实现它的run方法进行创建多个线程
java中基于Executor创建线程池的四种方式:
- newCachedThreadPool(缓存线程池,可以根据线程大小自动进行相关的回收)
- newSingleThreadPool(单线程池)
- newScheduledThreadPool(定时的线程池)
- newFixedThreadPool(定长的线程池)
1.1 通过线程池创建的代码实现
package com.qfedu.fmmall.thread;/*
**
*@author SmallMonkey
*@Date 2022/12/30 11:50
*
*
**/
import java.util.concurrent.*;
public class ThreadTest1 {
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
/*
* 1.继承Thread类
* 2. 实现Runnable接口没有返回值
* 3. 实现Callable接口 + FurtrueTask结合使用 (有返回值,可接收异常)
* 4. 通过线程池创建
*
*
* */
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main线程 start---------");
// Thread thread01 = new Thread01();
// thread01.start();
// Runnable01 runnable01 = new Runnable01();
// new Thread(runnable01).start();
// Runnable配合FutureTask使用也可以得到返回值
// System.out.println("main线程 end---------");
// FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
// new Thread(futureTask).start();
// //可以提到阻塞等待的结果
// Integer integer = futureTask.get();
// System.out.println("main线程 end---------" + integer);
// 实际开发中我们不会用到前面三种方式进行线程方式的创建,会使用线程池的方式进行线程的创建,
// 可以节约线程开销,和方面线程管理,性能稳定
executorService.submit(new Runnable01());
// 原生方式创建线程池
/*七大参数:
1. corePoolSize:最大核心线程数,会一起存在[unless allowCoreThreadTimeOut is set]
2. maximumPoolSize: 最大线程数量控制资源
3. keepAliveTime:释放空闲时间,释放的线程是(maximunPoolSize - corePoolSize),如果当前的空闲时间大于keepAliveTIme
4. TimeUnit:时间单位
5. BlockingQueue<Runnable>:阻塞队列,把多的任务放入阻塞队列,只要有线程空闲就拿出队列里面的任务进行执行。
6.threadFactory:线程的创建工厂
7. RejectedExceptionHandler handler: 队列满了指定具体的拒绝策略进行拒绝执行任务
*
new LinkedBlockingQueue<>(10000), 这个可以根据不同的业务场景设置不同的阻塞任务数量
* */
/*
* 面试题目: core 7 ,max 20,queue 50, 100个并发进来怎么执行
* 7个核心线程马上执行, 放入队列50个任务, 再开 13个线程执行, 剩下的30个使用拒绝策略
* 如果不想抛弃:使用CallerRunsPolicy
* */
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
20,
100,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
/*
* 工具类中Executor提供四种创建线程池的方式注意一下。
*
* */
// Executors.newSingleThreadExecutor() 核心线程数1个,最大线程也是1个,所有任务放在BlockiongQueue1个,1个执行
// public static ExecutorService newSingleThreadExecutor() {
// return new FinalizableDelegatedExecutorService
// (new ThreadPoolExecutor(1, 1,
// 0L, TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<Runnable>()));
// }
// Executors.newScheduledThreadPool() 做定时任务的线程池
// Executors.newCachedThreadPool() corePoolSize核心线程数是0,所有线程可以回收
// public static ExecutorService newCachedThreadPool() {
// return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
// 60L, TimeUnit.SECONDS,
// new SynchronousQueue<Runnable>());
// }
}
public static class Thread01 extends Thread{
@Override
public void run() {
System.out.println("Thread01子线程执行完毕,线程号:" + Thread.currentThread().getId());
int i = 6 / 3;
System.out.println("结果" + i);
}
}
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("Runnable01子线程执行完毕,线程号:" + Thread.currentThread().getId());
int i = 6 / 3;
System.out.println("结果" + i);
}
}
public static class Callable01 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("Callable01子线程执行完毕,线程号:" + Thread.currentThread().getId());
int i = 6 / 3;
System.out.println("结果" + i);
return i;
}
}
}
2. 共享锁和独占锁?
- 独占锁:每次只能有一个线程持有锁,它可以避免读读冲突,某个只读线程线程获取锁,其他的只读线程只可以等待。
- 共享锁:允许多个线程同时获取锁,并发访问资源。如ReadWriteLock.共享锁则是一种乐观锁,可以多个执行读操作访问共享资源。
3.重量级锁和轻量级锁,分段锁?
重量级锁:依赖于操作系统的MutexLock 所实现的锁我们称之为重量级锁。(synchronized----依赖于对象内部monitor来实现--------》依赖于底层的MutexLock实现,它们状态之间的转换需要的比较长的时间,所以synchronized的效率是非常低的).
分段锁:分段锁而非一种实际的锁,而是一种思想, CocurrentMap是学习分段锁的最好的实践。
4.CocurrentHashMap为什么 在线程的时候比Hashtable的效率更高?
CocurrentHashMap使用的是segment(分段锁),相当于多个HashMap,然后每个部分进行加锁。
HashTable:是多个线程使用一把锁,然后多个线程访问的时候只有一个可以访问,会导致阻塞问题。
5.TreeMap的理解?
实现了SortedMap,可以根据它的key进行升序排序
,key必须实现Comparable接口或者传入自定义的Comparator,
否则会抛出java.lang.ClassCastExcption异常。
6.异常处理?
Throwable是所有的异常处理的超类,包含Error和Exception.
Error:java运行时系统内部错误和内部资源耗尽。不会抛出这个异常
Exception:以包含RuntimeException和CheckException异常。抛出的一般是RuntimeException,这个一定是程序员的错误。
CheckExeception:外部错误,一般可以通过try/catch进行相应的捕获。
7.Throw和Throws的区别?
Throws是用在一个方法上的异常抛出,这个异常不一定发生,Throw这个是用在方法内部的,如果执行了这个语句,那么异常一定会发生,执行了这个语句后面就已经结束了。
8.索引的数据类型?
FullText,BTREE,RTREE,HASH.
-
FullText:,目前只有MyISAM引擎支持,全文索引,只有char,Text,varchar列支持全文索引。
-
BTREE:MYsql默认和最常用 的索引,将索引按照一定的算法存入一个树形(二叉树)结构中,每次从root开始遍历node,然后获取leafNode.
-
RTREE:不常用。
-
HASH: 由于HASH的唯一(几乎100%的唯一)及类似键值对的形式,很适合作为索引。