面试题突击(一)

网友投稿 718 2022-11-19

面试题突击(一)

面试题突击(一)

Java如何开启线程?怎么保证线程安全?

进程是系统资源调度的最小单位,线程是系统任务调度的最小单位。一个进程可以有多个线程,线程共享进程内的资源。

开启线程的方式:

继承Thread,重写run()方法

public class ThreadTest { public class MyThread extends Thread{ @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子线程执行完毕"); } } public static void main(String[] args) { MyThread t = new ThreadTest().new MyThread(); t.start(); System.out.println("父线程执行完毕"); }}

2.实现Runnable接口,重写run()方法

public class ThreadTest { public class MyRunnable implements Runnable{ @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子线程执行完毕"); } } public static void main(String[] args) { Thread t = new Thread(new ThreadTest().new MyRunnable()); t.start(); System.out.println("父线程执行完毕"); }}

3.实现Callable重写call()方法 借助Thread:

public class ThreadTest { public class MyCallable implements Callable { @Override public Integer call() throws Exception { int num = new Random().nextInt(5); Thread.sleep(num*1000); System.out.println("子线程执行完毕"+num); return num; } } public static void main(String[] args) { FutureTask futureTask = new FutureTask(new ThreadTest().new MyCallable()); Thread t = new Thread(futureTask); t.start(); System.out.println("父线程执行完毕"); try { System.out.println(futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}

线程池方式:

public class ThreadTest { public class MyCallable implements Callable { @Override public Integer call() throws Exception { int num = new Random().nextInt(5); Thread.sleep(num*1000); System.out.println("子线程执行完毕"+num); return num; } } public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); Future future = executorService.submit(new ThreadTest().new MyCallable()); System.out.println("父线程执行完毕"); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}

扩展,公平锁非公平锁

公平锁:按照线程申请锁的顺序,依次放入队列中,永远是排在第一位的线程获得锁 优点:不会有线程饿死,所有线程最终都会获得锁 缺点:降低了吞吐量,除了排在第一位的线程,其他线程都会阻塞,对CPU的开销比较大

非公平锁:需要获得锁的线程,先尝试获得锁,若未获得锁再进入队列中 优点:增加了吞吐量,CPU不必唤醒所有线程,减少系统开销 缺点:因为非公平,可能存在队列当中有线程饿死的情况

扩展,乐观锁和悲观锁

悲观锁:利用数据库的锁机制,修改前先对数据进行锁定的方式,叫做悲观锁

共享锁:读锁,多个事务共享一把锁排他锁:写锁,如果一个事务获取了锁,则其他事务不能只有等待该事务修改完成后才能进行修改乐观锁:采用版本号方式,每次修改检查版本号,防止数据被修改的方式,叫做乐观锁

volatile和synchronized区别?volatile能不能保证线程安全?DCL单例问什么要加volatile?

volatile是用来保证不同线程之间可见性,synchronized是用来加锁的,volatile适用用一个线程写,多个线程读的场景。

volatile只能保证线程之间的可见性,不是原子操作,是线程不安全的。

volatile能防止指令重排,防止在多线程情况下,因指令重排造成的线程不安全的情况。

Java线程锁机制是怎样的?偏向锁,轻量级锁,重量级锁有什么区别?锁机制是如何升级的?

下图来自图灵《金三银四为大家整理了68道高频java面试题,花点耐心看完,offer拿到手软!》

谈谈对AQS的理解?AQS是如何实现可重入锁的?

AQS是java线程同步框架,是java很多锁机制的核心。

有个信号量,相当于红绿灯,控制线程的流转有个双向链表,里面维护着头节点和尾节点

可重入锁场景下,state=0表示无锁,加一次锁就加一,释放一次就减一

ABC三个线程如何保证同时执行?如何保证依次执行?如何保证有序交错执行?

countDownLatch.await();countDownLatch.countDown(); 后面两个其实用个信号量可以了。

扩展,CountDownLatch,CylicBarrier,Semaphere

如何对一个字符串快速排序

Fork/Join框架:

public class ForkJoinCalculator implements Calculator{ ForkJoinPool pool; public ForkJoinCalculator(){ pool = new ForkJoinPool(); } private static class MyTask extends RecursiveTask{ int[] nums; int start; int end; public MyTask(int[] nums, int start, int end){ this.nums = nums; this.start = start; this.end = end; } @Override protected int[] compute() { if(start == end){ return nums; }else{ int mid = (start+end)/2; MyTask t1 = new MyTask(nums,start,mid); MyTask t2 = new MyTask(nums,mid+1,end); t1.fork(); t2.fork(); int []r1 = t1.join(); int []r2 = t2.join(); int[] tmp = new int[end-start+1]; int i1 = start; int i2 = mid+1; int ii = 0; while(i1 <= mid && i2 <= end){ if(r1[i1]

public class Main { public static void main(String[] args){ Main solution = new Main(); int[] its = new int[10000]; Random random = new Random(); for(int i = 0; i < 10000; i++){ its[i] = random.nextInt(1000); } int[] items = new ForkJoinCalculator().sort(its); for(int item:items){ System.out.print(item+" "); } System.out.println(); }}

public interface Calculator { int[] sort(int[] numbers);}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:分布式之全面了解Kafka的使用与特性
下一篇:LiveRTMP CPU占用问题调优(一)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~