栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程面试题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程面试题

多线程面试题(自用)
    多线程创建方式?哪种好?
    3种方式创建线程:
    a) 继承Thread类;b) 实现Runnable接口 c) 实现Callable接口
    实现Runnable比继承Thread类所具备的优势:
    a) 可以避免java中的单继承的局限性
    b) 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
    c) 线程池只能放入实现 Runable 或 Callable 类线程,不能直接放入继承Thread的类。
    d) 适合多个相同的程序代码的线程去共享同一个资源。
package com.test;
 
class MyThead extends Thread {
	private int ticket = 10;
	private String name;
    
	public MyThead(String name) {
		this.name = name;
	}
 
	public void run() {
		for (int i = 0; i < 500; i++) {
			 if (this.ticket>0) {
				System.out.println(this.name+"卖出第"+(10-this.ticket-- + 1)+"票");
			}
		}
	}
}
 
public class ThreadDemo {
	public static void main(String[] args) {
       MyThead mt1 = new MyThead("一号窗口");
       MyThead mt2 = new MyThead("二号窗口");
       MyThead mt3 = new MyThead("三号窗口");
       mt1.start();
       mt2.start();
       mt3.start();
	}
}
二号窗口卖出第1票
二号窗口卖出第2票
一号窗口卖出第1票
二号窗口卖出第3票
一号窗口卖出第2票
二号窗口卖出第4票
二号窗口卖出第5票
二号窗口卖出第6票
三号窗口卖出第1票
三号窗口卖出第2票
三号窗口卖出第3票
三号窗口卖出第4票
三号窗口卖出第5票
三号窗口卖出第6票
三号窗口卖出第7票
三号窗口卖出第8票
三号窗口卖出第9票
三号窗口卖出第10票
二号窗口卖出第7票
二号窗口卖出第8票
一号窗口卖出第3票
一号窗口卖出第4票
一号窗口卖出第5票
一号窗口卖出第6票
一号窗口卖出第7票
一号窗口卖出第8票
一号窗口卖出第9票
一号窗口卖出第10票
二号窗口卖出第9票
二号窗口卖出第10票
package com.test;
 
class MyThead implements Runnable {
 
	private int ticket = 10;
	
 
	public void run() {
		for (int i = 0; i < 500; i++) {
			if (this.ticket > 0) {
				System.out.println(Thread.currentThread().getName() + "卖出第"
						+ (10 - this.ticket-- + 1) + "票");
			}
		}
	}
}
 
public class ThreadDemo {
	public static void main(String[] args) {
		// 设计三个现程
		MyThead mt = new MyThead();
		Thread t1 = new Thread(mt, "一号窗口");
		Thread t2 = new Thread(mt, "二号窗口");
		Thread t3 = new Thread(mt, "三号窗口");
		t1.start();
		t2.start();
		t3.start();
	}
}
一号窗口卖出第1票
一号窗口卖出第4票
二号窗口卖出第2票
三号窗口卖出第3票
二号窗口卖出第6票
三号窗口卖出第7票
一号窗口卖出第5票
一号窗口卖出第9票
一号窗口卖出第10票
二号窗口卖出第8票

    线程的状态有哪些?

    新建状态:新创建一个线程对象。就绪状态:线程对象创建后,其他线程调用了该对象的 start()方法。 该状态的线程位于可运行线程池中,变得可运行,等待获取 CPU 的使用权。运行状态:就绪状态的线程获取了 CPU,执行程序代码。阻塞状态:阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止 运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞状态分三种:
    a) 等待阻塞:运行的线程执行 wait()方法,JVM 会把该线程放入等待池中。(wait 会释放持有的锁)
    b) 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用, 则 JVM 会把该线程放入锁池中。
    c) 其他阻塞:运行的线程执行 sleep()或 join()方法,JVM 会把该线程置为阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)死亡状态:线程执行完了或者因异常退出了 run()方法,该线程结束生命周期。

    用户线程和守护线程的区别?

    虚拟机必须确保用户线程执行完毕虚拟机不用等待守护线程执行完毕守护线程:垃圾回收在Daemon中创建的线程也是Daemon线程

    sleep与wait的区别?

    sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其 他线程,但是监控状态依然保持,到时后会自动恢复。调用 sleep 不会释放对象锁。 sleep() 使当前线程进入阻塞状态,在指定时间内不会执行。wait 是 Object 类的方法,对此对象调用 wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
    区别:
    a) 这两个方法来自不同的类分别是 Thread 和 Object。
    b) 最主要是 sleep 方法没有释放锁,而 wait 方法释放了锁,使得其他线程可以使用同 步控制块或者方法。
    c) wait,notify 和 notifyAll 只能在同步控制方法或者同步控制块里面使用,而 sleep 可 以在任何地方使用(使用范围)。
    d) sleep 必须捕获异常,而 wait,notify 和 notifyAll 不需要捕获异常。

    yield join notify 和 notifyAll区别
    a) yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。 如果没有的话,那么 yield()方法将不会起作用,并且由可执行状态后马上又被执行。
    b) join 方法是用于在某一个线程的执行过程中调用另一个线程执行,等到被调用的线程执行结束后,再继续执行当前线程。
    c) notify 方法只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程 等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管 理的实现。
    d) notifyAll 会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。

    什么是中断线程?中断线程有哪几种方式?
    中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作。
    a) 当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的,如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。
    b) Thread.interrupt()方法: 作用是中断线程。将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程。interrupt()方法只是改变中断状态,不会中断一个正在运行的线程。需要用户自己去监视线程的状态为并做处理。

    什么是死锁?多线程如何避免死锁?
    所谓死锁是指多个进 程因竞争资源而造成的一种僵局(互相等待),若无外力作用, 这些进程都将无法向前推进。产生死锁四个条件:
    a) 互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一 段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程 只能等待。
    b) 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。
    c) 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求, 而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
    d) 循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的 资源同时被链中下一个进程所请求。
    避免死锁:
    a) 加锁顺序(线程按照一定的顺序加锁)
    b) 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求, 并释放自己占有的锁)
    c) 死锁检测

    多线程的好处以及问题?
    a) 进程间不能共享内存,但线程之间可以共享内存非常容易。
    b) 发挥多核CPU的优势。

    多线程间的信息交互
    a) notify()方法:唤醒在此对象监视器上等待的单个线程。
    b) notifyAll()方法:唤醒在此对象监视器上等待的所有线程。
    c) wait()方法:让占用了这个同步对象的线程,临时释放当前的占用,并且等待。

    多线程公用一个变量需要注意什么?
    a) 当我们在线程对象(Runnable)中定义,run方法会修改该变量时,如果有多个线程同时使用该线程同时使用该线程对象,那么就会造成全程变量的值被同时修改,造成错误。
    b) ThreadLocal是JDK引入的一个机制,它用于解决线程间共享变量,使用ThreadLocal声明的变量,即使在线程中属于全局变量,针对每个线程来讲,这个变量也是独立的。
    c) volatile变量每次被线程访问的时候,都强迫线程从主内存重读该变量的最新值,而当该变量发生变化时,也会强迫线程将最新的值刷会主内存中。这样一来,不同的线程都能看到该变量的最新值。

    线程的通信方式?

    有synchronized关键字修饰的方法、语句块。wait/notify 机制。

    Java线程池的实现?

    newSingleThreadExecutor;创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。newFixedThreadPool;创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。newCachedThreadPool;创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。newScheduledThreadPool;创建一个定长线程池,支持定时及周期性任务执行。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/764293.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号