`

Java面试中的多线程问题

    博客分类:
  • Java
阅读更多
0.Java 中多线程同步是什么?

在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个 Java 线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。

1.解释实现多线程的几种方法?

一 Java 线程可以实现 Runnable 接口或者继承 Thread 类来实现,当你打算多重继承时,优先选择实现 Runnable。

2.Thread.start ()与 Thread.run ()有什么区别?

Thread.start ()方法(native)启动线程,使之进入就绪状态,当 cpu 分配时间该线程时,由 JVM 调度执行 run ()方法。

3.为什么需要 run ()和 start ()方法,我们可以只用 run ()方法来完成任务吗?

我们需要 run ()&start ()这两个方法是因为 JVM 创建一个单独的线程不同于普通方法的调用,所以这项工作由线程的 start 方法来完成,start 由本地方法实现,需要显示地被调用,使用这俩个方法的另外一个好处是任何一个对象都可以作为线程运行,只要实现了 Runnable 接口,这就避免因继承了 Thread 类而造成的 Java 的多继承问题。

4.什么是 ThreadLocal 类,怎么使用它?

ThreadLocal 是一个线程级别的局部变量,并非“本地线程”。ThreadLocal 为每个使用该变量的线程提供了一个独立的变量副本,每个线程修改副本时不影响其它线程对象的副本(译者注)。

下面是线程局部变量(ThreadLocal variables)的关键点:

一个线程局部变量(ThreadLocal variables)为每个线程方便地提供了一个单独的变量。

ThreadLocal 实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。

当多个线程访问 ThreadLocal 实例时,每个线程维护 ThreadLocal 提供的独立的变量副本。

常用的使用可在 DAO 模式中见到,当 DAO 类作为一个单例类时,数据库链接(connection)被每一个线程独立的维护,互不影响。(基于线程的单例)

ThreadLocal 难于理解,下面这些引用连接有助于你更好的理解它。

《Good article on ThreadLocal on IBM DeveloperWorks 》、《理解 ThreadLocal》、《Managing data : Good example》、《Refer Java API Docs》

5.什么时候抛出 InvalidMonitorStateException 异常,为什么?

调用 wait ()/notify ()/notifyAll ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出 IllegalMonitorStateException 的异常(也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用 wait ()/notify ()/notifyAll ()时)。由于该异常是 RuntimeExcpetion 的子类,所以该异常不一定要捕获(尽管你可以捕获只要你愿意).作为 RuntimeException,此类异常不会在 wait (),notify (),notifyAll ()的方法签名提及。

6.Sleep ()、suspend ()和 wait ()之间有什么区别?

Thread.sleep ()使当前线程在指定的时间处于“非运行”(Not Runnable)状态。线程一直持有对象的监视器。比如一个线程当前在一个同步块或同步方法中,其它线程不能进入该块或方法中。如果另一线程调用了 interrupt ()方法,它将唤醒那个“睡眠的”线程。

注意:sleep ()是一个静态方法。这意味着只对当前线程有效,一个常见的错误是调用t.sleep (),(这里的t是一个不同于当前线程的线程)。即便是执行t.sleep (),也是当前线程进入睡眠,而不是t线程。t.suspend ()是过时的方法,使用 suspend ()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend ()容易引起死锁问题。

object.wait ()使当前线程出于“不可运行”状态,和 sleep ()不同的是 wait 是 object 的方法而不是 thread。调用 object.wait ()时,线程先要获取这个对象的对象锁,当前线程必须在锁对象保持同步,把当前线程添加到等待队列中,随后另一线程可以同步同一个对象锁来调用 object.notify (),这样将唤醒原来等待中的线程,然后释放该锁。基本上 wait ()/notify ()与 sleep ()/interrupt ()类似,只是前者需要获取对象锁。

7.在静态方法上使用同步时会发生什么事?

同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。

8.当一个同步方法已经执行,线程能够调用对象上的非同步实例方法吗?

可以,一个非同步方法总是可以被调用而不会有任何问题。实际上,Java 没有为非同步方法做任何检查,锁对象仅仅在同步方法或者同步代码块中检查。如果一个方法没有声明为同步,即使你在使用共享数据 Java 照样会调用,而不会做检查是否安全,所以在这种情况下要特别小心。一个方法是否声明为同步取决于临界区访问(critial section access),如果方法不访问临界区(共享资源或者数据结构)就没必要声明为同步的。

下面有一个示例说明:Common 类有两个方法 synchronizedMethod1()和 method1(),MyThread 类在独立的线程中调用这两个方法。
public class Common {

public synchronized void synchronizedMethod1() {
System.out.println (“synchronizedMethod1 called”);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
System.out.println (“synchronizedMethod1 done”);
}
public void method1() {
System.out.println (“Method 1 called”);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
System.out.println (“Method 1 done”);
}
}
public class MyThread extends Thread {
private int id = 0;
private Common common;

public MyThread (String name, int no, Common object) {
super(name);
common = object;
id = no;
}

public void run () {
System.out.println (“Running Thread” + this.getName ());
try {
if (id == 0) {
common.synchronizedMethod1();
} else {
common.method1();
}
} catch (Exception e) {
e.printStackTrace ();
}
}

public static void main (String[] args) {
Common c = new Common ();
MyThread t1 = new MyThread (“MyThread-1″, 0, c);
MyThread t2 = new MyThread (“MyThread-2″, 1, c);
t1.start ();
t2.start ();
}
}

这里是程序的输出:

Running ThreadMyThread-1
synchronizedMethod1 called
Running ThreadMyThread-2
Method 1 called
synchronizedMethod1 done
Method 1 done


结果表明即使 synchronizedMethod1()方法执行了,method1()也会被调用。

9.在一个对象上两个线程可以调用两个不同的同步实例方法吗?

不能,因为一个对象已经同步了实例方法,线程获取了对象的对象锁。所以只有执行完该方法释放对象锁后才能执行其它同步方法。看下面代码示例非常清晰:Common 类有 synchronizedMethod1()和 synchronizedMethod2()方法,MyThread 调用这两个方法。
public class Common {
public synchronized void synchronizedMethod1() {
System.out.println (“synchronizedMethod1 called”);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
System.out.println (“synchronizedMethod1 done”);
}

public synchronized void synchronizedMethod2() {
System.out.println (“synchronizedMethod2 called”);
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
System.out.println (“synchronizedMethod2 done”);
}
}
public class MyThread extends Thread {
private int id = 0;
private Common common;

public MyThread (String name, int no, Common object) {
super(name);
common = object;
id = no;
}

public void run () {
System.out.println (“Running Thread” + this.getName ());
try {
if (id == 0) {
common.synchronizedMethod1();
} else {
common.synchronizedMethod2();
}
} catch (Exception e) {
e.printStackTrace ();
}
}

public static void main (String[] args) {
Common c = new Common ();
MyThread t1 = new MyThread (“MyThread-1″, 0, c);
MyThread t2 = new MyThread (“MyThread-2″, 1, c);
t1.start ();
t2.start ();
}
}

10.什么是死锁

死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就 JavaAPI 而言,线程死锁可能发生在一下情况。

当两个线程相互调用 Thread.join ()
当两个线程使用嵌套的同步块,一个线程占用了另外一个线程必需的锁,互相等待时被阻塞就有可能出现死锁。
11.什么是线程饿死,什么是活锁?

线程饿死和活锁虽然不想是死锁一样的常见问题,但是对于并发编程的设计者来说就像一次邂逅一样。

当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。JavaAPI 中线程活锁可能发生在以下情形:

当所有线程在程序中执行 Object.wait (0),参数为 0 的 wait 方法。程序将发生活锁直到在相应的对象上有线程调用 Object.notify ()或者 Object.notifyAll ()。
当所有线程卡在无限循环中。Java程序员面试中的多线程问题
分享到:
评论

相关推荐

    面试中多线程问题

    "面试中多线程问题" 多线程是 Java 编程中一个重要的概念,掌握多线程可以帮助开发者更好地编写高效、稳定的程序。以下是面试中常见的多线程问题和解释: 1. 实现多线程的几种方法? Java 中有两种方式可以实现多...

    java经典多线程面试题

    在Java中,多线程是一种非常重要的编程概念,...这些面试题涵盖了Java多线程编程的基础知识、同步机制、线程间通信以及并发集合类等多个方面。在准备面试时,对这些问题进行深入理解和准备,能够有效提升面试的成功率。

    多线程面试题

    在Java编程领域,多线程是面试中常见且重要的知识点,尤其对于系统设计和高并发处理的岗位至关重要。本文将围绕“多线程面试题”这一主题,深入探讨相关概念、技术及其应用。 1. **线程的概念**:线程是程序执行的...

    java面试题_多线程(68题).pdf

    Java中的多线程是面试中常见的话题,涵盖了操作系统的基础概念以及Java并发库的高级特性。以下是对这些知识点的详细解释: 1. **线程**:线程是操作系统调度的基本单元,一个进程中可以有多个线程并发执行。在多...

    java多线程面试题和答案

    以下是一些关于Java多线程的面试题及其答案,涵盖了基础概念、并发控制、线程安全以及性能优化等方面。 1. **什么是Java多线程?** 多线程是指在单个程序中同时执行多个线程,这样可以提高应用程序的效率和响应...

    java面试题之多线程.pdf

    Java中的多线程是面试中常见的话题,因为它在并发编程中扮演着重要角色。线程允许应用程序同时执行多个任务,从而提高系统效率和响应性。理解线程的概念、创建方式以及状态转换对于Java开发者至关重要。 1. **线程...

    个人总结40个Java多线程面试问题和答案

    Java多线程面试问题和答案总结 Java多线程是一种高级的编程技术,能够充分发挥多核CPU的优势,防止阻塞,简化模型建立,提高程序的效率和可维护性。下面是40个Java多线程面试问题和答案的总结,涵盖了多线程的基本...

    java多线程面试题

    以上知识点涵盖了多线程编程在Java中的基础理论和实际操作,包括线程的创建、运行、异常处理以及线程安全等问题,这些都是在进行Java多线程面试时常见的问题,对于理解和掌握Java多线程编程至关重要。

    史上最全 Java 多线程面试题及答案

    了解这些核心概念后,开发者可以更好地应对Java多线程面试中可能出现的问题,同时也能在实际项目中灵活运用多线程技术,提升程序性能。多线程编程虽然复杂,但掌握好相关的工具和原理,就能有效地解决并发问题,编写...

    JAVA并发多线程的面试问题及答案-java多线程并发面试题.docx

    JAVA并发多线程是Java技术面试中面试官比较喜欢问的问题之一。在这里,我们将从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。 1. 多线程和并发问题 在 ...

    面试官:公司项目中Java的多线程一般用在哪些场景?.zip

    面试官:公司项目中Java的多线程一般用在哪些场景面试官:公司项目中Java的多线程一般用在哪些场景面试官:公司项目中Java的多线程一般用在哪些场景面试官:公司项目中Java的多线程一般用在哪些场景面试官:公司项目...

    热门Java面试多线程面试题问答Top50共17页.pdf

    【标题】"热门Java面试多线程面试题问答Top50共17页.pdf" 提供了一份关于Java多线程面试的重要资源,涵盖了面试中可能会遇到的50个关键问题和答案,共计17页。这表明该文档深入探讨了Java编程中的并发处理和线程管理...

    JAVA多线程面试问题

    JAVA多线程面试问题

    Java程序员面试中的多线程问题

    ### Java程序员面试中的多线程问题详解 #### 1. 多线程同步的理解 **多线程同步**是Java多线程编程中一个非常重要的概念。在并发环境中,多个线程可能会同时访问和修改同一份共享数据。如果没有适当的同步机制,...

    Java面试题-线程多线程.pdf

    同步控制是多线程中防止数据竞争的关键。Java提供了多种同步机制: - **synchronized 关键字**:用于修饰方法或代码块,确保同一时间只有一个线程能执行同步代码。它提供了两种用法:修饰实例方法和静态方法,以及...

    2022java面试题、JVM面试题、多线程面试题、并发编程、Redis面试题、MySQL面试题、Java2022面试题

    2022java面试题、JVM面试题、多线程面试题、并发编程、Redis面试题、MySQL面试题、Java2022面试题、Netty面试题、Elasticsearch面试题、Tomcat面试题、Dubbo面试题、Kafka面试题、Linux面试题、2021面试题、java面试...

    java面试题之多线程

    在Java多线程编程中,面试题常常涉及到线程的基本概念、同步与异步的区别、线程同步方法以及Java提供的并发工具类。下面我们将深入探讨这些知识点。 1. **线程间的协作**: - `sleep()` 和 `wait()` 的区别:`...

    Java面试宝典2021-多线程,锁,同步.pdf

    最新java面试关于多线程,锁,同步相关知识总结

    10万字总结java面试题和答案(八股文之一)Java面试题指南

    多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 Spring面试题 Spring Boot面试题 Spring Cloud面试题 RabbitMQ面试题 Dubbo 面试题 MyBatis 面试题 ZooKeeper 面试题 数据结构...

    国外JAVA面试多线程问题分享.pdf

    本文将详细解析几个常见的Java多线程面试问题及其答案。 1. **Java中的多线程同步是什么?** 多线程同步是一种机制,用于在并发环境中控制对共享资源的访问,防止数据不一致和竞态条件的发生。Java提供了多种同步...

Global site tag (gtag.js) - Google Analytics