java多线程面试题整理及答案(2018年)

电脑杂谈  发布时间:2019-06-27 22:05:35  来源:网络整理

java多线程死锁_线程死锁_线程 死锁

b、 线程是操作系统能够进行运算调度的最单位,它被包含在进程之中,是进程中的实际运行单位。线程是操作系统能够进行运算调度的最单元. 它被包含在进程中. 是进程中的实际运作单位. 一条线程指的是进程中一个单一顺序的控制流. 一个进程中可以并发多个线程. 每个线程并行执行不通的任务.。其实也有各自的真实pid,但由结构隐藏了,对外的pid为主进程的pid5)线程对操作系统来说就是进程,因此对信号的处理是以进程为单位分发的6)线程总数受限于系统进程数7)系统管理线程的瓶颈:所有线程由管理线程管理8)线程之间的调度是由内核调度器来处理的9)由于计算线程本地数据的方法是基于堆栈地址的位置。

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

java.lang.thread 类的实例就是一个线程但是它需要调用 java.lang.runnable 接口来执行,由于线程类本身就是调用的 runnable 接口所以你可以继承 java.lang.thread 类或者直接调用 runnable 接口来重写 run ()方法实现线程。java.lang.thread 类的实例就是一个线程但是它需要调用java.lang.runnable接口来执行,由于线程类本身就是调用的runnable接口所以你可以继承java.lang.thread 类或者直接调用runnable接口来重写run()方法实现线程。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为java中的继承是单继承,一个类有一个父类,如果继承了thread类就无法再继承其他类了,显然使用runnable接口更为灵活。

这个问题是上题的后续,大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使 用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好 了。

中国竞彩网当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。 (void)detachnewthreadselector:(sel)selector totarget:(id)target withobject:(id)argument直接将操作添加到线程中并启动,也可以使用对象方法- (instancetype)initwithtarget:(id)target selector:(sel)selector object:(id)argument创建一个线程对象,然后调用start方法启动线程。c) 创建继承thread的自定义类对象,调用线程的start()方法,start()方法的作用:启动线程,并自动调用run()方法。

中国竞彩网Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在 JDK1.5增加的。它们的主要区别是Callable的 call() 方法可以返回值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。

CyclicBarrier 和 CountDownLatch 都可以用来让一组线程等待其它线程。与 CyclicBarrier 不同的是,CountdownLatch 不能重新使用。

Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一 个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如,先行发生关系确保 了:

中国竞彩网我强烈建议大家阅读《Java并发编程实践》第十六章来加深对Java内存模型的理解。

volatile是一个特殊的修饰符,只有成员变量才能使用它。在Java并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的。volatile变量可以保证下一个读取操作会在前一个写操作之后发生,就是上一题的volatile变量规则。

如果你的代码所在的进程中有多个线程在同时运行java多线程死锁中国竞彩网,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量 的值也和预期的是一样的,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分 成两组,线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。

线程死锁_java多线程死锁_线程 死锁

中国竞彩网竞态条件会导致程序在并发情况下出现一些bugs。多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了, 那么整个程序就会出现一些不确定的bugs。这种bugs很难发现而且会重复出现,因为线程间的随机竞争。

中国竞彩网Java提供了很丰富的API但没有为停止线程提供API。JDK 1.0本来有一些像stop(), suspend() 和 resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了,之后Java API的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当run() 或者 call() 方法执行完的时候线程会自动结束,如果要手动结束一个线程,你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程。

中国竞彩网这是我在一次面试中遇到的一个很刁钻的Java面试题, 简单的说,如果异常没有被捕获该线程将会停止执行。Thread.UncaughtExceptionHandler是用于处理未捕获异常造成线程突然中 断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候JVM会使用Thread.getUncaughtExceptionHandler()来 查询线程的UncaughtExceptionHandler并将线程和异常作为参数传递给handler的uncaughtException()方法 进行处理。

-- david a. patterson & john l. hennessy 并发编程模型的分类 java ,c# 共享内存 pthread,win32线程库并发编程 jvm上的scala 消息传递 google 的go ericsson的erlang 共享内存模型的线程间通信 通过共享变量 线程a 的写-读来通信 线程b首先,线程a写 然后,线程b读 共享内存空间 a 1 消息传递模型的线程间通信 线程之间通过明确 的发送消息来通信 线程a 线程a向b发送消息 线程b 读/写 读/写独立内存空间a 独立内存空间b a 1 b 2 它们就是想对着干。a.通信依赖性:对象创建的线程试图并发修改对象的临界区时发生通信依赖性关系,线程间机制使用互。高并发:vert.x有一个简单的异步编程模型(actor模型),非常适用于非阻塞的应用程序,它可以用最数量的操作系统线程来达到10s、100s甚至百万级别的并发连接(vert.x内置了和操作系统内核数量相等的线程数来处理verticles,这样你就可以不必使用更多的线程就可以实现一个完美的非阻塞应用)。

而notifyall()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。wait()是object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyall()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。wait()是object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyall()方法)时才能唤醒等待池中的线程。

这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的时候,你要说明为什么把这些方法放在 Object类里是有意义的,还有不把它放在Thread类里的原因。一个很明显的原因是JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通 过线程获得。如果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Thread类中,线程正在等待的是哪个锁 就不明显了。简单的说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中因为锁属于对象。

ThreadLocal是Java里一种特殊的变量。每个线程都有一个ThreadLocal就是每个线程都拥有了自己独立的一个变量,竞争条件被 彻底消除了。它是为创建代价高昂的对象获取线程安全的好方法,比如你可以用ThreadLocal让SimpleDateFormat变成线程安全的,因 为那个类创建代价高昂且每次调用都需要创建不同的实例所以不值得在局部范围使用它,如果为每个线程提供一个自己独有的变量拷贝,将大大提高效率。首先,通 过复用减少了代价高昂的对象的创建个数。其次,你在没有使用高代价的同步或者不变性的情况下获得了线程安全。线程局部变量的另一个不错的例子是 ThreadLocalRandom类,它在多线程环境中减少了创建代价高昂的Random对象的个数。

中国竞彩网1) client提交请求对象封装成packet对象放入outgoingqueue队列,并调用packet.wait()阻塞当前线程。只有当运算完成的时候结果才能取回,如果运算尚未完成get方法将会阻塞。只有当运算完成的时候结果才能取回,如果运算尚未完成 get 方法将会阻塞。

interrupted()和isInterrupted()的主要区别是前者会将中断状态清除而后者不会。Java多线程的中断机制是用内部标识来实现的,调用Thread.interrupt()来中断一个线程就会设置中断标识为true。当中断线程调用静态方法Thread.interrupted()来 检查中断状态时,中断状态会被清零。而非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛 出InterruptedException异常的方法都会将中断状态清零。无论如何,一个线程的中断状态有有可能被其它线程调用中断来改变。

主要是因为Java API强制要求这样做,如果你不这么做,你的代码会抛出IllegalMonitorStateException异常。还有一个原因是为了避免wait和notify之间产生竞态条件。

处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出。因此,当一个等待线程醒来 时,不能认为它原来的等待状态仍然是有效的,在notify()方法调用之后和等待线程醒来之前这段时间它可能会改变。这就是在循环中使用wait()方 法效果更好的原因,你可以在Eclipse中创建模板调用wait和notify试一试。如果你想了解更多关于这个问题的内容,我推荐你阅读《Effective Java》这本书中的线程和同步章节。

线程死锁_java多线程死锁_线程 死锁

中国竞彩网不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有他们如何实现的线程安全上。这是另外一个容易遵循且受益巨大的最佳实践,并发集合比同步集合的可扩展性更好,所以在并发编程时使用并发集合效果更好。多用并发集合少用同步集合这是另外一个容易遵循且受益巨大的最佳实践,并发集合比同步集合的可扩展性更好,所以在并发编程时使用并发集合效果更好。


本文来自电脑杂谈,转载请注明本文网址:
http://dawgspsp.com/a/jisuanjixue/article-108878-1.html

相关阅读
发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论