多线程面试常考问题

1) 什么是线程?

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。

 

2) 线程和进程有什么区别?

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

 

3) 如何在Java中实现线程?

继承java.lang.Thread

实现Runnable接口

 

4) Runnable相对于Thread的优势在哪?

java不允许多继承,因此实现了Runnable接口的类可以再继承其他类。

方便资源共享,通过实现Runnable可以共享一个对象实例

 

5) Thread 类中的start() run() 方法有什么区别?

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法。run()方法只是在原来的线程中调用,并没有新的线程启动。

 

6) 什么是线程安全?

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

 

7) 如何在两个线程间共享数据?

通过实现Runnable接口或者通过阻塞队列

 

8) Javanotify notifyAll有什么区别?

notify会唤醒所有等待线程里的某一个,notifyAll会唤醒所有等待线程,并允许它们争夺锁。

 

9) ThreadinterruptedisInterrupted方法的区别?

两个方法都是用来判断当前线程是否中断。不同的是interrupted会清除中断状态,isInterrupted却不会。

 

10) 为什么waitnotify方法要在同步块中调用?

只有在调用线程拥有某个对象的独占锁时,才能够调用该对象的wait(),notify()notifyAll()方法。否则,代码会抛出IllegalMonitorStateException异常。

 

11) Java中堆和栈有什么不同?

栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量、方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域,对象都在堆里创建。为了提升效率,线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

12)什么是线程池? 为什么要使用它?

创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。

13)有三个线程T1,T2,T3,怎么确保它们按顺序执行?
  • 通过join方法阻塞线程
import java.util.concurrent.TimeUnit;

public class Test3 {

	public static void main(String[] args) throws InterruptedException {
		for(int i=0; i<3; i++){
			Thread th = new MyThread();
			th.start();
			th.join();
		}
		System.out.println("All finished");
	}

}

class MyThread extends Thread {
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + " is runninng");
		try {
			TimeUnit.SECONDS.sleep(Math.round(Math.random() * 3));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
  • 通过单线程的线程池实现线程串行执行
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test5 {
	public static void main(String[] args) {
		ExecutorService pool = Executors.newSingleThreadExecutor();
		for (int i = 0; i < 3; i++) {
			pool.submit(new TestRunnable("thread-" + i));
		}
		pool.shutdown();
	}

}

class TestRunnable implements Runnable {
	private String name;
	public TestRunnable(String name) {
		this.name = name;
	}

	@Override
	public void run() {
		try {
			System.out.println("Thread " + name + " is running");
			TimeUnit.SECONDS.sleep(Math.round(Math.random() * 3));
			System.out.println("Thread " + name + " finished");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

  • 线程里面开启线程,并通过join阻塞
import java.util.concurrent.TimeUnit;

public class Test4 {

	public static void main(String[] args) throws InterruptedException {
		Thread th = new MyThread3();
		th.start();
	}

}

class MyThread1 extends Thread {
	@Override
	public void run() {
		System.out.println("Thread1 is runninng");
	}
}

class MyThread2 extends Thread {
	@Override
	public void run() {
		Thread th = new MyThread1();
		th.start();
		try {
			th.join();
			TimeUnit.SECONDS.sleep(Math.round(Math.random() * 3));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Thread2 is runninng");
	}
}

class MyThread3 extends Thread {
	@Override
	public void run() {
		Thread th = new MyThread2();
		th.start();
		try {
			th.join();
			TimeUnit.SECONDS.sleep(Math.round(Math.random() * 3));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Thread3 is runninng");
	}
}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值