1、什么是多线程同步
多线程同步:多个线程按照预定的先后次序进行运行。如果没有同步,当一个Java线程在修改一二个共享变量时,另一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。
2、解释实现多线程的几种方法
1、继承Thread类,重写run方法
public class MyThread1 { public static void main(String[] args) { // TODO 自动生成的方法存根 Thread thread1 = new ExtendsThread("线程1"); Thread thread2 = new ExtendsThread("线程2"); thread1.start(); thread2.start(); } } class ExtendsThread extends Thread{ ExtendsThread(){ super(); } ExtendsThread(String name){ super(name); } public void run() { System.out.println("当前线程的名字是: " + this.getName()); } }
2、实现Runnable接口,重写run方法
public class MyThread2 { public static void main(String[] args) { Thread thread = new Thread(new ImplementsRunnable()); thread.start();//开启线程 } } class ImplementsRunnable implements Runnable{ public void run() { System.out.println("实现run方法"); } }
3、实现Callable接口,重写call方法
FutureTask是Runnable的实现类 Class FutureTask<V> //可取消的异步计算,该类提供了一个Future的基本实现,具有启动和取消计算的方法,查询计算是否完整,并检索计算结果。结果只能在计算完成后才能检索;如果计算尚未完成,则get方法将阻止。一旦计算完成,则无法重新启动或取消计算(除非使用runAndReset()调用计算) //构造方法 FutureFask(Callable<V> callable);//将在运行时执行给定的Callable FutureTask(Runnable runnable,V result);//创建一个FutureTask,将在运行时执行给定的Runnable,并安排get将在成功完成后返回给定的结果 //主要方法 V get();//等待计算完成,然后检索其结果
public class MyThread3 { public static void main(String[] args) throws Throwable { // TODO 自动生成的方法存根 Callable<Integer> callable = new ImplementsCallable(); FutureTask<Integer> futureTask = new FutureTask<>(callable); new Thread(futureTask).start(); System.out.println(futureTask.get()); } } class ImplementsCallable implements Callable<Integer>{ @Override public Integer call() throws Exception { return 99; } }
4、线程池
public class MyThread { public static void main(String[] args) { /* * ExecutorService 线程池的实现类 * Executor 负责线程的使用和调度的根接口 * ThreadPoolExecutor 线程池的实现类 * ScheduledExecutorService 接口,负责线程的调度 * ScheduledThreadPoolExecutor */ //创建线程池 ExecutorService pool = Executors.newFixedThreadPool(5); ThreadPoolDemo demo = new ThreadPoolDemo(); //为线程池中的线程分配任务,使用submit方法,传入的参数可以是Runnable的实现类,也可以是Callable的实现类 for(int i = 1; i <= 5;i++) { pool.submit(demo); } //关闭线程池 pool.shutdown(); } } class ThreadPoolDemo implements Runnable{ /*多线程共享数据*/ private int i = 0; @Override public void run() { while(i <= 50) { System.out.println(Thread.currentThread().getName() + "---" + i++); } } }
3、Thread.start()与Thread.run()有什么区别
start:用start方法来启动线程,真正实现了多线程运行,这时不需要等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这是此线程就处于就绪(可运行)状态,并没有运行,一旦得到cpu的时间片,就会开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。
run:只是类中的一个普通的方法,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,顺序执行即可,还是要等待run方法体执行完毕后才可以继续执行下面的代码,这样就没有线程的目的。
总结一下区别:start方法是开启一个线程,当CPU给其分配时间时,就执行run方法,是另一个线程在执行run方法,而不是主线程。run方法就是一个普通的方法,如果直接调用run方法,那么线程将失去意义,run方法还是在主线程中执行。
4、为什么需要run()和start()方法,可以只用run()方法来完成么
参见上一题。如果只用run方法则失去线程的意义。
5、什么是ThreadLocal类,怎么使用
6、什么时候抛出IllegalMonitorStateException异常,为什么?
7、Sleep()、suspend()和wait()之间有什么区别?
8、在静态方法上使用同步时会发生什么事?
9、当一个同步方法已经执行,线程能够调用对象上的非同步实例方法吗?
10、 在一个对象上两个线程可以调用两个不同的同步实例方法吗?
11、 什么是死锁
死锁就是两个或者两个以上的线程被无线的阻塞,线程之间相互等到所需要的资源。例如,线程A获得线程B在等待的锁,而线程B又获得了线程A在等待的锁,线程A和线程B都不释放锁,进入无线等待状态。
- 当两个线程相互调用Thread.jion()
- 当两个线程使用嵌套的同步块,一个线程占用另外一个线程必须要的锁,互相等待时被阻塞就有可能出现死锁
12、什么是线程饿死,什么是活锁?
活锁:两个线程的优先级相同,相互谦让,两个线程就一直在谦让的等待过程中
饿死:某个线程一直在让其他线程先获得锁,自己一直处理等待状态
13.什么是线程?
14.线程和进程有什么区别?
15.如何在Java中实现线程?
16.Java多线程有几种实现方法,都是什么?哪一种方式比较优秀?同步有几种实现方法,都是什么?
17.Java实现线程用Runnable还是Thread?
18.Thread类中的start() 和 run() 方法有什么区别?
19.为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?
20.在java中wait和sleep方法的不同?
21.Java中Runnable和Callable有什么不同?
22.Java中CyclicBarrier 和 CountDownLatch有什么不同?
23.用Java实现阻塞队列
24.Java中你怎样唤醒一个阻塞的线程?
25、volatile的作用
26、synchronized的作用
27、volatile与synchronized的区别
28、线程的sleep()方法和yield()的区别:
29、进程与线程的概念
30、进程与线程的区别联系