多线程面试题

合集下载

120道Java面试题以及答案陆小马功钟浩

120道Java面试题以及答案陆小马功钟浩

多线程、并发及线程的基础问题1)Java 中能创建volatile 数组吗?能,Java 中可以创建volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。

我的意思是,如果改变引用指向的数组,将会受到volatile 的保护,但是如果多个线程同时改变数组的元素,volatile 标示符就不能起到之前的保护作用了。

2)volatile 能使得一个非原子操作变成原子操作吗?一个典型的例子是在类中有一个long 类型的成员变量。

如果你知道该成员变量会被多个线程访问,如计数器、价格等,你最好是将其设置为volatile。

为什么?因为Java 中读取long 类型变量不是原子的,需要分成两步,如果一个线程正在修改该long 变量的值,另一个线程可能只能看到该值的一半(前32 位)。

但是对一个volatile 型的long 或double 变量的读写是原子。

3)volatile 修饰符的有过什么实践?一种实践是用volatile 修饰long 和double 变量,使其能按原子类型来读写。

double 和long 都是64位宽,因此对这两种类型的读是分为两部分的,第一次读取第一个32 位,然后再读剩下的32 位,这个过程不是原子的,但Java 中volatile 型的long 或double 变量的读写是原子的。

volatile 修复符的另一个作用是提供内存屏障(memory barrier),例如在分布式框架中的应用。

简单的说,就是当你写一个volatile 变量之前,Java 内存模型会插入一个写屏障(write barrier),读一个volatile 变量之前,会插入一个读屏障(read barrier)。

意思就是说,在你写一个volatile 域时,能保证任何线程都能看到你写的值,同时,在写之前,也能保证任何数值的更新对所有线程是可见的,因为内存屏障会将其他所有写的值更新到缓存。

4)volatile 类型变量提供什么保证?volatile 变量提供顺序和可见性保证,例如,JVM 或者JIT为了获得更好的性能会对语句重排序,但是volatile 类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。

android 多线程面试题

android 多线程面试题

android 多线程面试题Android多线程面试题Android多线程是一个重要的技术,对于开发者来说,掌握多线程编程是非常必要的。

在Android面试中,经常会出现与多线程相关的问题。

下面将介绍一些常见的Android多线程面试题,希望能够帮助你在面试中更好地回答问题。

1. 什么是多线程?多线程是指在一个进程中同时执行多个任务的技术。

在Android中,多线程可以实现在后台同时进行多个任务,以提升用户体验和应用性能。

2. 在Android中有哪些实现多线程的方式?在Android中,有以下几种实现多线程的方式:a. 使用Thread类:可以通过继承Thread类或者创建Thread匿名内部类的方式来创建线程对象,重写run()方法来定义线程执行的操作。

b. 使用Runnable接口:通过创建一个实现Runnable接口的类的实例,将其作为参数传递给Thread类的构造函数来创建线程。

c. 使用HandlerThread类:HandlerThread是继承自Thread的一个类,它内部封装了一个Looper和Handler,可以方便地实现线程间的通信。

d. 使用AsyncTask类:AsyncTask是一个封装了异步操作的类,它可以在后台执行耗时操作,并在主线程更新UI。

3. 什么是主线程和子线程?主线程是指应用程序的主要执行线程,也称为UI线程。

它负责处理用户交互、更新UI等操作。

子线程是在主线程之外创建的线程,用于执行一些耗时的操作,以保证主线程不会被阻塞。

4. 如何在子线程中更新UI?在Android中,UI更新必须在主线程中进行,但有时需要在子线程中执行一些耗时操作。

可以通过以下几种方式在子线程中更新UI:a. 使用Handler:可以在子线程中通过Handler发送消息给主线程,然后在主线程中通过Handler处理消息,更新UI。

b. 使用runOnUiThread()方法:可以在子线程中通过Activity的runOnUiThread()方法来直接更新UI。

JAVA并发多线程的面试问题及答案

JAVA并发多线程的面试问题及答案

JAVA并发多线程的面试问题及答案多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。

在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。

下面就由为大家介绍一下JAVA并发多线程的面试问题及答案的文章,欢迎阅读。

JAVA并发多线程的面试问题及答案篇11)现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?这个线程问题通常会在第一轮或电话面试阶段被问到后的是检测你对〃join”方法是否熟悉。

这个多线程问题比较简单,可以用join 方法实现。

2)在Java中Lock接口比synchronized块的优势是什么?你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它?lock接口在多线程和并发编程中最大的优势是它们为读和写分别提供了锁,它能满足你写像ConcurrentHashM叩这样的高性能数据结构和有条件的阻塞。

Java线程面试的问题越来越会根据面试者的回答来提问。

我强烈建议在你去参加多线程的面试之前认真读一下Locks,因为当前其大量用于构建电子交易终统的客户端缓存和交易连接空间。

3)在java中wait和sleep方法的不同通常会在电话面试中经常被问到的Java线程面试问题。

最大的不同是在等待时wait会释放锁,而sleep 一直持有锁。

Wait通常被用于线程间交互,sleep通常被用于暂停执行。

4)用Java实现阻塞队列。

这是一个相对艰难的多线程面试问题,它能达到很多的目的。

第一,它可以检测侯选者是否能实际的用Java线程写程序;第二,可以检测侯选者对并发场景的理解,并且你可以根据这个问很多问题。

如果他用wait ()和notify()方法来实现阻塞队列,你可以要求他用最新的Java 5中的并发类来再写一次。

JAVA并发多线程的面试问题及答案篇21)用Java写代码来解决生产者;;消费者问题。

多线程常见面试题及答案

多线程常见面试题及答案

多线程常见⾯试题及答案1、如何在Java中实现线程(4种)?1.继承Thread类,重写run⽅法(其实Thread类本⾝也实现了Runnable接⼝)2.实现Runnable接⼝,重写run⽅法3.实现Callable接⼝,重写call⽅法(有返回值)4.使⽤线程池(有返回值)2、在具体多线程编程实践中,如何选⽤Runnable还是Thread?Java中实现多线程有两种⽅法:继承Thread类、实现Runnable接⼝,在程序开发中只要是多线程,肯定永远以实现Runnable接⼝为主,因为实现Runnable接⼝相⽐继承Thread类有如下优势:1、可以避免由于Java的单继承特性⽽带来的局限;2、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独⽴的;适合多个相同程序代码的线程区处理同⼀资源的情况。

3、Thread类中的start()和run()⽅法有什么区别?start()⽅法来启动线程,真正实现了多线程运⾏,这时⽆需等待run⽅法体代码执⾏完毕⽽直接继续执⾏下⾯的代码:通过调⽤Thread类的start()⽅法来启动⼀个线程,这时此线程是处于就绪状态,并没有运⾏。

然后通过此Thread类调⽤⽅法run()来完成其运⾏操作的,这⾥⽅法run()称为线程体,它包含了要执⾏的这个线程的内容,Run⽅法运⾏结束,此线程终⽌,⽽CPU再运⾏其它线程。

run()⽅法当作普通⽅法的⽅式调⽤,程序还是要顺序执⾏,还是要等待run⽅法体执⾏完毕后才可继续执⾏下⾯的代码:⽽如果直接⽤run⽅法,这只是调⽤⼀个⽅法⽽已,程序中依然只有主线程–这⼀个线程,其程序执⾏路径还是只有⼀条,这样就没有达到多线程的⽬的。

4、Java中Runnable和Callable有什么不同相同点:1. 两者都是接⼝;(废话)2. 两者都可⽤来编写多线程程序;3. 两者都需要调⽤Thread.start()启动线程;不同点:1. 两者最⼤的不同点是:实现Callable接⼝的任务线程能返回执⾏结果;⽽实现Runnable接⼝的任务线程不能返回结果;2. Callable接⼝的call()⽅法允许抛出异常;⽽Runnable接⼝的run()⽅法的异常只能在内部消化,不能继续上抛;注意点:Callable接⼝⽀持返回执⾏结果,此时需要调⽤FutureTask.get()⽅法实现,此⽅法会阻塞主线程直到获取‘将来’结果;当不调⽤此⽅法时,主线程不会阻塞!5、如何避免死锁?1. 加锁顺序按照顺序加锁是⼀种有效的死锁预防机制。

ios多线程面试题

ios多线程面试题

ios多线程面试题在进行iOS多线程面试时,以下是一些常见的问题及其答案,帮助您更好地准备面试。

多线程是指同时执行多个线程的概念,它可以提高程序的运行效率。

在iOS开发中,多线程常用于处理耗时的操作,如网络请求、数据解析等,以避免阻塞主线程造成界面卡顿。

以下将介绍一些与iOS多线程相关的面试题目。

1. 什么是线程?线程是程序中的执行单元,是CPU调度和分派的基本单位。

每个进程至少有一个线程,称为主线程。

多线程是指同时运行多个线程。

2. iOS中常用的多线程技术有哪些?iOS中常用的多线程技术有以下几种:- Grand Central Dispatch (GCD)- NSOperationQueue- Thread3. Grand Central Dispatch (GCD)是什么?GCD是Apple推出的一套自动管理线程的技术,它使用了线程池的概念,通过将任务放入队列中,自动调度执行任务的线程。

GCD使用起来简单高效,是iOS开发中常用的多线程技术。

4. GCD中的队列有哪两种类型?GCD中的队列分为以下两种类型:- 串行队列:按照先进先出的顺序,依次执行队列中的任务。

- 并发队列:可以同时执行多个任务,任务之间的执行顺序不确定。

5. 什么是同步任务和异步任务?- 同步任务:在当前线程中执行,会阻塞当前线程,等待任务执行完毕后再继续执行后续代码。

- 异步任务:在新的线程中执行,不会阻塞当前线程,可以继续执行后续代码。

6. GCD中的dispatch_group有什么作用?dispatch_group用于在异步任务执行完毕后,执行特定代码。

dispatch_group_enter与dispatch_group_leave配合使用,用于标记任务的开始和结束,通过dispatch_group_notify方法执行指定代码。

7. NSOperationQueue与GCD有什么区别?- NSOperationQueue是基于GCD的更高级的多线程技术,支持添加依赖关系、取消操作等功能。

java面试题库java面试题目及答案(3篇)

java面试题库java面试题目及答案(3篇)

第1篇一、基础知识1. Java简介题目:请简述Java的基本特点。

答案:- 简单易学:Java设计之初就考虑了易学性,使用面向对象编程。

- 原生跨平台:Java通过JVM(Java虚拟机)实现跨平台运行。

- 安全性:Java提供了强大的安全机制,如沙箱安全模型。

- 体系结构中立:Java不依赖于特定的硬件或操作系统。

- 高效:Java的运行速度接近C/C++。

- 多线程:Java内置多线程支持,便于实现并发处理。

- 动态性:Java在运行时可以进行扩展和修改。

2. Java虚拟机题目:请解释Java虚拟机(JVM)的作用。

答案:JVM是Java程序的运行环境,其主要作用包括:- 将Java字节码转换为本地机器码。

- 管理内存,包括堆、栈、方法区等。

- 提供垃圾回收机制。

- 管理线程和同步。

3. Java内存模型题目:请简述Java内存模型的组成。

答案:Java内存模型主要由以下部分组成:- 堆(Heap):存储对象实例和数组。

- 栈(Stack):存储局部变量和方法调用。

- 方法区(Method Area):存储类信息、常量、静态变量等。

- 本地方法栈(Native Method Stack):存储本地方法调用的相关数据。

- 程序计数器(Program Counter Register):存储线程的当前指令地址。

4. Java关键字题目:请列举并解释Java中的几个关键字。

答案:- `public`:表示访问权限为公开。

- `private`:表示访问权限为私有。

- `protected`:表示访问权限为受保护。

- `static`:表示属于类本身,而非对象实例。

- `final`:表示常量或方法不能被修改。

- `synchronized`:表示线程同步。

- `transient`:表示数据在序列化时不会被持久化。

二、面向对象编程5. 类和对象题目:请解释类和对象之间的关系。

答案:类是对象的模板,对象是类的实例。

多线程面试题c++ 4个线程设计问题

多线程面试题c++ 4个线程设计问题

多线程面试题c++ 4个线程设计问题
1.题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码子线程与主线程必有一个满足条件(flag == num),不满足条件的那个线程不可能获取unique_lock(会在wait中释放),只有满足条件的线程才能获取锁,执行程序
2.题目:编写一个程序,开启3个线程,这3个线程的ID分别为A、
B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

3.题目(google笔试题):有四个线程1、2、3、4。

线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。

初始都为空。

现要让四个文件呈如下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....
D:4 1 2 3 4 1....
4.题目:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。

5.题目:编写程序完成如下功能:
1)有一int型全局变量g_Flag初始值为0
2)在主线称中起动线程1,打印“this is thread1”,并将g_Flag 设置为1
3)在主线称中启动线程2,打印“this is thread2”,并将g_Flag 设置为2
4)线程序1需要在线程2退出后才能退出
5)主线程在检测到g_Flag从1变为2,或者从2变为1的时候退出。

最全多线程经典面试题和答案

最全多线程经典面试题和答案

最全多线程经典⾯试题和答案Java实现线程有哪⼏种⽅式?1、继承Thread类实现多线程2、实现Runnable接⼝⽅式实现多线程3、使⽤ExecutorService、Callable、Future实现有返回结果的多线程多线程同步有哪⼏种⽅法?Synchronized关键字,Lock锁实现,分布式锁等。

Runnable和Thread⽤哪个好?Java不⽀持类的多重继承,但允许你实现多个接⼝。

所以如果你要继承其他类,也为了减少类之间的耦合性,Runnable会更好。

Java中notify和notifyAll有什么区别?notify()⽅法不能唤醒某个具体的线程,所以只有⼀个线程在等待的时候它才有⽤武之地。

⽽notifyAll()唤醒所有线程并允许他们争夺锁确保了⾄少有⼀个线程能继续运⾏。

为什么wait/notify/notifyAll这些⽅法不在thread类⾥⾯?这是个设计相关的问题,它考察的是⾯试者对现有系统和⼀些普遍存在但看起来不合理的事物的看法。

回答这些问题的时候,你要说明为什么把这些⽅法放在Object类⾥是有意义的,还有不把它放在Thread类⾥的原因。

⼀个很明显的原因是JAVA提供的锁是对象级的⽽不是线程级的,每个对象都有锁,通过线程获得。

如果线程需要等待某些锁那么调⽤对象中的wait()⽅法就有意义了。

如果wait()⽅法定义在Thread类中,线程正在等待的是哪个锁就不明显了。

简单的说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中因为锁属于对象。

为什么wait和notify⽅法要在同步块中调⽤?主要是因为Java API强制要求这样做,如果你不这么做,你的代码会抛出IllegalMonitorStateException异常。

还有⼀个原因是为了避免wait 和notify之间产⽣竞态条件。

什么是死锁?如何避免死锁?死锁就是两个线程相互等待对⽅释放对象锁。

c 面试题 多线程

c  面试题 多线程

c 面试题多线程多线程面试题多线程是计算机科学中一个重要的概念,它指的是在一个程序中同时执行多个线程。

这种并发性的设计可以提高程序的效率和响应能力。

在进行多线程的面试中,通常会涉及一些重要的问题和概念。

本文将针对多线程面试题进行讨论和解答。

一、什么是多线程?多线程是指在一个程序中同时执行多个线程的技术。

每个线程可以独立地执行不同的任务,而不会相互干扰。

多线程可以提高程序的效率和响应能力,特别是在需要进行复杂计算或者处理大量数据的情况下。

二、线程和进程的区别是什么?线程是进程中的一个执行单元,一个进程可以包含多个线程。

线程共享进程的资源,如内存空间和文件句柄。

进程是操作系统分配资源的基本单位,每个进程都有自己独立的内存空间和执行权。

三、请描述线程同步和线程互斥的概念。

线程同步是指多个线程之间的协调和合作,以确保它们能够正确地访问共享数据。

线程互斥是指使得同一时间只有一个线程访问某个共享资源,其他线程必须等待。

常用的线程同步和互斥的机制有锁、信号量、条件变量等。

四、请解释以下概念:互斥锁、读写锁、自旋锁和信号量。

互斥锁(Mutex)是一种用于控制多个线程对共享资源进行互斥访问的机制。

只有获得互斥锁的线程才能进行访问,其他线程必须等待。

读写锁(ReadWrite Lock)是一种用于控制读写操作的机制。

多个线程可以同时进行读操作,但只有一个线程可以进行写操作,且在写操作期间禁止读操作。

自旋锁(Spinlock)是一种基于忙等待的锁机制。

它不会让线程进入睡眠状态,而是通过循环不断检查锁状态,直到获取到锁。

信号量(Semaphore)是一种允许多个线程同时访问某个资源的机制。

它可以用来控制同时访问某个资源的线程数量。

五、什么是死锁?如何避免死锁?死锁是指两个或多个线程之间相互等待对方释放资源而无法继续执行的情况。

避免死锁的方法包括:避免使用多个锁、确保加锁的顺序一致、尽量减少锁的持有时间、使用死锁检测和解除机制等。

java多线程试题

java多线程试题

狂翔IT工作室多线程试程一.选择题1.下列说法中,正确的一项是() AA.单处理机的计算机上,2个纯种一官半职直不能并发执行B.单处理机的计算机上,2个线程实际能够并发执行C.一个线程可以包含多个线程D.一个进程只能包含一个线程2.下列说法中错误的一项是()AA.线程就是程序B.线程是一个程序的单个执行流B.多线程是指一个程序的多个执行流D.多线程用于实现并发3.下列哪个一个操作不能使线程从等待阻塞状态进入对象阻塞状态(D)A.等待阴塞状态下的线程被notify()唤B.等待阻塞状态下的纯种被interrput()中断C.等待时间到D.等待阻塞状态下的线程调用wait()方法4.下列哪个方法可以使线程从运行状态进入其他阻塞状态(A)A.sleepB.waitC.yieldD.start5.下列不是进程组成部分的一项是(D)A.代码B.数据C.内核状态D.显示器6.下列哪一个不属于java线程模型的组成部分(D)A.虚拟的CPUB.虚拟CPU执行的代码C. 代码所操作的数据D.执行流7.下列说法中错误的一项是(C)A.Java中的第一个线程都属于某个线程组B.线程只能在其创建时设置所属的线程组C.线程创建之后,可以从一个线程组转移到另一个线程组D.新建的线程默认情况下属于其父线程所属的线程组8.下列不属于线程组成部分的一项是(C)A.程序计数器B.堆栈C. 进程地十空间中的代码D.栈指针9.下列关于JA V A线程模型的说法中,错误的一项是(A)A.Java线程模型包括计算机的CPUB.代码可以与其他线程共享C. 数据可以被多个线程共享D.线程模型在ng.Thread类中被定义10.下列说法中错误的一项是(D)A.一个线程是一个Thread类的实例B.线程从传递给纯种的Runnable实例run()方法开始执行C.线程操作的数据来自Runnable实例D.新建的线程调用start()方法就能立即进入运行状态11.下列关于Thread类提供的线程控制方法的说法中,错误的一项是(D)A.在线程A中执行线程B的join()方法,则线程A等待直到B执行完成B.线程A通过调用interrupt()方法来中断其阻塞状态C.若线程A调用方法isAlive()返回值为true,则说明A正在执行中D.currentThread()方法返回当前线程的引用12.下列说法中,错误的一项是()A.对象锁在synchronized()语句执行完之后由持有它的线程返还B.对象锁在synchronized()语句中出现异常时由持有它的线程返还C.当持有锁的线程调用了该对象的wait()方法时,线程将释放其持有的锁D.当持有锁的线程调用了该对象的构造方法时,线程将释放其持有的锁13.下面的哪一个关键字通宵用来对对象的加锁,从而使得对对象的访问是排他的 AA.sirialize B transient C synchronized D static14.下列关于线程的说法以中,正确的一项是(D)A.由同一类创建的多个线程都同时运行结束B.创建线程只能通过继承ng.Thread类C.调用suspend()方法暂停的一个线程将不会再被重新执行D.程序的执行完毕与超级线程(daemon threads)无关15.下列说法中错误的一项是(C)A.可串行化的类必须实现Serializable接口B.可串行化的类中的静态变量可以不被串行化C.private数据访问权限能够限制数据不被串行化D.对象串行化使用java语言提供的默认机制16.下列说法中错误的一项是(C)A.可串行化的类必须实现Serializable接口B.可串行化的类中的静态变量可以不被串行化C.private数据访问权限能够限制数据不被串行化D.对象串行化java语言提供的默认机制17.下列说法中正确的一项是(A)A.代码和数据是进程的组成部分B.代码和数据是线程的组成部分C. 进程是轻型的线程D.线程中包括线程18. 下列说法中错误的一项是(C)A.java的纯种体由Thread类的run()方法定义B.线程创建时已经确定了提供线程体的对象C.在程序中通过调用Thread类的run()方法创建线程对象D.java中每一个线程都有自己的名字19. 下列说法中错误的一项是(B)A.共享数据的所有访问都必须使用synchronized加锁B.共享数据的访问不一定全部使用synchronized加锁C.所有的对共享数据的访问都是临界区D.临界区必须使用syschronized标识20.下列有关线程的叙述中正确的一项是(B)A.一旦一个线程被创建,它就立即开始运行B.使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行C.当一个线程因为抢占机制而停止运行时,它被放在可运行队列的前面D.一个线程可能因为不同的原因而终止并进入终止状态二.填空题1. 在操作系统中,被称做轻型的进程是线程2. 多线程程序设计的含义是可以将一个程序任务分成几个并行的任务3. 在Java程序中,run()方法的实现有两种方式:实现Runnable接口和继。

java 同步面试题

java 同步面试题

java 同步面试题Java同步面试题同步是多线程编程中经常涉及的重要概念之一。

当多个线程同时访问共享资源时,可能会导致数据不一致的问题。

为了避免这种情况的发生,我们可以利用Java中提供的同步机制来实现线程间的协调和数据的一致性。

在本文中,将介绍一些与Java同步相关的面试题以及它们的解答。

1. 什么是线程安全?线程安全是指多个线程并发访问共享资源时,不会发生不正确的结果。

线程安全的代码可以在多线程环境中正确地工作,不会出现数据异常或不一致的问题。

2. Java中如何实现线程的同步?Java中实现线程同步的方式有以下几种:- 使用synchronized关键字:通过在方法或代码块前添加synchronized关键字,可以确保同一时间只有一个线程执行该方法或代码块,从而保证数据的一致性。

- 使用ReentrantLock类:该类提供了与synchronized关键字类似的功能,但更加灵活,可以实现更复杂的同步逻辑。

- 使用volatile关键字:volatile关键字用于修饰共享变量,可以确保变量的可见性,但不能保证原子性。

3. synchronized关键字和ReentrantLock类有什么区别?synchronized关键字是Java语言内置的同步机制,使用简单,但功能相对较弱。

它只能实现基本的同步功能,无法实现一些高级的同步需求。

而ReentrantLock类则是Java.util.concurrent包中提供的一种可重入锁实现,功能更为强大,可以实现更灵活的同步控制。

与synchronized关键字相比,ReentrantLock类提供了一些额外的功能,例如允许分离读和写,支持多个读者和写者并发访问等。

此外,ReentrantLock类还提供了更细粒度的锁控制,可以通过tryLock()方法尝试非阻塞地获取锁,并可以配合Condition对象实现等待和唤醒机制。

4. 什么是死锁?如何避免死锁?死锁是指两个或多个线程互相持有对方所需的资源,导致所有线程都处于等待状态,无法继续执行的情况。

【7】IOS面试题-线程网络2

【7】IOS面试题-线程网络2

1.多线程都有哪些实现,GCD要注意些什么。

三种线程优缺点?(1)NSThread:轻量级的方式(具有很少的规则和惯例,依赖的东西少),比较底层和原始。

需要自己手动管理线程的生命周期,同步的时候需要加锁来控制线程执行顺序,会增加系统开销。

不推荐使用。

(2)NSOperationQueue:一个NSoperation对象可以通过调用start方法执行任务,默认是同步执行;也可以将NSOperation添加到一个NSOperationQueue中执行,这时是异步的。

通过这个方式开启线程后,可以中途停止、继续、取消等操作。

如果想控制线程执行顺序,可以通过添加依赖完成。

优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。

对于上传、下载这种复杂的操作,推荐使用。

(3)GCD:苹果提供的,异步执行。

提高了代码执行效率和多核的利用率,性能更好。

对于复杂的不推荐使用,但是简单的提交数据推荐使用。

2. 在哪里用过哪些第三方库,在哪获取第三库?读过第三方代码没有?在开发的过程中,用过很多第三方类库,AFNetWorking、SDWebImage、MBProgressHUD、FMDB、EGOTableViewPullRefresh、ShareSDK等。

注意:提到的可能面试官都会问到。

大多是从Github、CocoaChina地方等下载。

第三方类库主要是用它的功能,对于比较优秀的代码自己也读了一下,写的非常棒,比如。

(这个时候可以详细介绍一个你最熟悉的第三方类库)3. 多个iphone版本适配?最简单有效的方式是通过autolayout+sizeclass来进行适配的,但是这种方式的缺点需要添加的约束比较多,对于手写的代码非常麻烦。

一般手写代码进行布局的时候,会选择第三方类库来做,比如FLKAutoLayout,可以用简单的一句代码完成对一个控件添加的全部约束,非常实用。

4. 上拉加载更多,下拉刷新如何实现?用EGOTableViewPullRefresh做的,上拉的时候,从服务器取一组新的数据,加到数组中,刷新界面;下拉的时候,从服务器取数据,更新数组,刷新界面。

进程和线程面试题

进程和线程面试题

进程和线程⾯试题1、线程和进程线程:线程是进程的⼀个实体,是CPU调度和分派的基本单元。

进程:进程是具有⼀定独⽴功能的程序,它是系统进程资源分配和调度的⼀个独⽴单元。

区别:(1)⼀个线程只属于⼀个进程,⼀个进程包含⼀个或者多个线程。

(2)进程拥有独⽴的内存单元,⽽多个线程共享内存。

(3)进程的创建调⽤fork或者vfork,⽽线程的创建调⽤pthead_create,进程结束后它拥有的所有线程都将销毁,⽽线程的结束不会影响同个进程中的其他线程的结束。

(4)线程是轻量级的进程,它的创建和销毁所需要的时间⽐进程⼩很多,所有操作系统中的执⾏功能都是创建线程去完成的。

(5)线程中执⾏时⼀般都要进⾏同步和互斥,因为他们共享同⼀进程的资源。

2、死锁?死锁产⽣的原因?死锁的必要条件?怎么处理死锁?死锁:死锁是指两个或者两个以上的进程在执⾏过程中,由于竞争资源或者由于彼此通信⽽造成的⼀种阻塞的现象。

死锁原因:系统资源不⾜、相互竞争资源。

请求资源顺序不当死锁的必要条件:1.互斥条件:⼀个资源每次只能被⼀个进程使⽤。

2.请求和保持条件:⼀个进程因请求资源⽽阻塞时,对已获得的资源保持不放。

3.不可剥夺条件:进程已获得的资源,在未使⽤完之前,不能强⾏剥夺,只能在进程使⽤完时由⾃⼰释放。

4.循环等待条件:若⼲进程之间形成⼀种头尾相接的循环等待资源关系。

避免死锁的⽅法:因为互斥是不可改变的,所以只能破坏其他三个条件中的⼀个来解除死锁,⽅法:剥夺资源、杀死其中⼀个线程。

避免死锁最简单的⽅法就是阻⽌循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以⼀定的顺序做操作来避免死锁。

3、如何在Java中实现线程?(1)继承Thread类(2)实现Runnable接⼝(3)实现Callable接⼝通过FutureTask包装器来创建Thread线程(4)使⽤ExecutorService、Callable、Future实现有返回结果的多线程4、⽤Runnable还是Thread?Java不⽀持类的多重继承,但允许你调⽤多个接⼝(当然是调⽤Runnable接⼝更好)5、Thread类中start()和run()⽅法有什么区别?(1)start()⽅法被⽤来启动新创建的线程,⽽start()内部调⽤了run()⽅法。

Java线程面试题Top50

Java线程面试题Top50

下面是Java线程相关的热门面试题,你可以用它来好好准备面试。

1) 什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。

程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。

比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。

Java 在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点。

欲了解更多详细信息请点击这里。

2) 线程和进程有什么区别?线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。

不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。

别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

更多详细信息请点击这里。

3) 如何在Java中实现线程?在语言层面有两种方式。

ng.Thread 类的实例就是一个线程但是它需要调用ng.Runnable接口来执行,由于线程类本身就是调用的Runnable接口所以你可以继承ng.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。

更多详细信息请点击这里.4) 用Runnable还是Thread?这个问题是上题的后续,大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。

所以如果你要继承其他类,当然是调用Runnable接口好了。

更多详细信息请点击这里。

6) Thread 类中的start() 和run() 方法有什么区别?这个问题经常被问到,但还是能从此区分出面试者对Java线程模型的理解程度。

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。

当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

多线程面试题及答案

多线程面试题及答案

多线程面试题及答案多线程是面试中常常涉及的一个重要话题。

面试官会通过提问关于多线程的问题来评估你对于并发编程的理解程度以及解决并发问题的能力。

下面是一些常见的多线程面试题及其答案。

1. 什么是线程?什么是多线程?答:线程是指操作系统能够进行运算调度的最小单位。

多线程是指在一个程序中运行多个线程,每个线程可以并发执行不同的任务。

2. 线程和进程有什么区别?答:线程是进程的子任务,一个进程可以包含多个线程。

进程拥有独立的内存空间,而线程共享同一进程的内存空间。

线程之间的切换比进程之间的切换更加高效。

3. 什么是线程安全?答:线程安全是指当多个线程同时访问一个共享资源时,保证该资源在并发情况下仍然能够正常工作,不会产生不一致或者异常的结果。

4. 如何创建线程?答:创建线程的方式有两种:继承Thread类和实现Runnable接口。

继承Thread类需要重写run()方法,实现Runnable接口需要实现run()方法。

可以通过调用start()方法来启动线程。

5. 什么是线程同步?答:线程同步是指多个线程之间按一定的顺序访问共享资源。

通过线程同步可以避免多个线程同时修改一个共享资源而引发的数据不一致的问题。

6. 什么是死锁?答:死锁是指两个或多个线程无限期地等待彼此持有的资源的情况。

当多个线程都在等待对方释放资源时,系统无法继续执行。

7. 如何避免死锁?答:避免死锁的方法有:避免使用多个锁;按照相同的顺序获取锁;设置超时时间;使用资源分级的方式。

8. 什么是线程池?答:线程池是一种线程复用的机制。

它包含一个线程队列,用于存放任务,并提供一种调度机制,控制并发的线程数。

9. 什么是线程安全的集合?答:线程安全的集合是在多线程环境下使用的数据结构,保证多个线程对集合的操作不会出现数据不一致的情况。

例如,线程安全的集合包括ConcurrentHashMap、ConcurrentLinkedQueue等。

10. 什么是死锁检测?答:死锁检测是一种机制,用于发现并解决死锁问题。

15个顶级Java多线程面试题及答案

15个顶级Java多线程面试题及答案

15 个顶级 Java 多线程面试题及答案1)此刻有 T1、T2、 T3 三个线程,你如何保证 T2 在 T1 履行完后履行, T3 在 T2 履行完后履行这个线程问题往常会在第一轮或电话面试阶段被问到,目的是检测你对”join ”方法能否熟悉。

这个多线程问题比较简单,能够用join 方法实现。

2)在 Java 中 Lock 接口比 synchronized 块的优势是什么你需要实现一个高效的缓存,它允很多个用户读,但只同意一个用户写,以此来保持它的完好性,你会如何去实现它lock 接口在多线程和并发编程中最大的优势是它们为读和写分别供给了锁,它能知足你写像ConcurrentHashMap 这样的高性能数据构造和有条件的堵塞。

Java 线程面试的问题愈来愈会依据面试者的回答来发问。

我激烈建议在你去参加多线程的面试以前仔细读一下Locks,因为目前其大批用于建立电子交易终统的客户端缓存和交易连结空间。

3)在 java 中 wait 和 sleep 方法的不一样往常会在电话面试中常常被问到的Java线程面试问题。

最大的不一样是在等候时wait 会开释锁,而 sleep 向来拥有锁。

Wait 往常被用于线程间交互,sleep 往常被用于暂停履行。

4)用 Java 实现堵塞行列。

这是一个相对困难的多线程面试问题,它能达到好多的目的。

第一,它能够检测侯选者能否能实质的用 Java 线程写程序;第二,能够检测侯选者对并发场景的理解,而且你能够依据这个问好多问题。

假如他用 wait() 和 notify() 方法来实现堵塞行列,你能够要求他用最新的Java 5中的并发类来再写一次。

5)用 Java 写代码来解决生产者——花费者问题。

与上边的问题很近似,但这个问题更经典,有些时候面试都会问下边的问题。

在Java中怎么解决生产者——花费者问题,自然有好多解决方法,我已经分享了一种用堵塞行列实现的方法。

有些时候他们甚至会问怎么实现哲学家进餐问题。

多线程面试题目(3篇)

多线程面试题目(3篇)

第1篇1. 什么是多线程?多线程是一种程序执行方式,允许程序同时执行多个线程,每个线程可以执行不同的任务。

2. 多线程有哪些优点?(1)提高程序的执行效率,充分利用多核CPU资源;(2)防止程序阻塞,提高用户体验;(3)简化程序设计,使程序结构更清晰。

3. 什么是线程?线程是程序执行的最小单元,是进程的一部分。

每个线程都有自己的堆栈、寄存器和程序计数器。

4. 什么是线程池?线程池是一组预先创建的线程,用于执行多个任务。

线程池可以减少线程创建和销毁的开销,提高程序性能。

5. 什么是同步?同步是线程之间的一种协调机制,确保同一时间只有一个线程访问共享资源。

6. 什么是互斥锁?互斥锁是一种同步机制,用于保护共享资源,确保同一时间只有一个线程访问该资源。

7. 什么是条件变量?条件变量是一种线程间的通信机制,用于线程之间的同步。

二、多线程实现方式1. Java中的多线程实现方式(1)继承Thread类:通过继承Thread类,重写run()方法,创建线程对象。

(2)实现Runnable接口:通过实现Runnable接口,重写run()方法,创建线程对象。

(3)使用Callable和Future:Callable接口与Runnable接口类似,但返回值。

Future接口用于获取Callable接口的返回值。

2. C中的多线程实现方式(1)继承Thread类:与Java类似,通过继承Thread类,重写Run()方法,创建线程对象。

(2)实现Runnable接口:与Java类似,通过实现Runnable接口,重写Run()方法,创建线程对象。

(3)使用Task和TaskCompletionSource:Task是C中的异步编程模型,TaskCompletionSource用于获取异步操作的结果。

3. Python中的多线程实现方式(1)使用threading模块:Python中的threading模块提供了创建线程、同步机制等功能。

java工程师面试题及答案

java工程师面试题及答案

java工程师面试题及答案Java工程师面试中,面试官通常会通过一系列技术问题来评估候选人的技术能力和经验。

以下是一些常见的Java面试题及答案,供参考:1. Java和C++的主要区别是什么?- Java是一种纯面向对象的语言,而C++支持面向过程和面向对象两种编程范式。

- Java不支持指针操作,而C++支持。

- Java有垃圾回收机制,而C++需要手动管理内存。

- Java是跨平台的,而C++不是。

2. 什么是JVM?- JVM(Java虚拟机)是一个可以执行Java字节码的虚拟计算机。

它将Java源代码编译成字节码,然后在JVM上运行。

3. 什么是多线程?- 多线程是程序设计中的一种方法,允许两个或多个线程同时执行。

Java通过`Thread`类和`Runnable`接口来实现多线程。

4. 同步和异步的区别是什么?- 同步是指多个线程访问共享资源时,一次只允许一个线程访问,这样可以防止数据不一致。

- 异步是指多个线程可以同时访问共享资源,但需要额外的机制来保证数据的一致性。

5. Java中的集合框架有哪些?- Java集合框架包括`List`、`Set`、`Map`等接口,以及它们的实现类如`ArrayList`、`HashSet`、`HashMap`等。

6. 什么是泛型?- 泛型是一种类型安全的特性,它允许在编译时检查类型,从而避免类型转换的错误。

泛型在Java 5中被引入。

7. Java中的异常处理机制是怎样的?- Java使用`try`、`catch`和`finally`块来处理异常。

`try`块包含可能会抛出异常的代码,`catch`块捕获并处理异常,`finally`块则无论是否发生异常都会执行。

8. 什么是Java反射?- 反射允许程序在运行时查询、访问和修改类和对象的属性和方法。

它在Java中是通过`ng.reflect`包实现的。

9. 什么是序列化?- 序列化是将对象的状态信息转换为可以存储或传输的格式的过程。

黑马面试题

黑马面试题
暴力反射的理解
类加载器的委托机制
4,面向对象的理解,举例说明继承,多态,还有一个想不起来了
5,动态代理和代理的区别
获取动态代理的步骤
6,JDK1.5的新特性有哪些
7,集合框架(基本上全部都说出来了)
什么遍历的方法有几种,TreeSet保持不重复的机制
一个框架都让我背下来了
8,还有从7K里面挑出来一个说说思路,实现方式(这个挂了。因为没看)
1,多线程创建的两种方式
Sleep和wait的区别
线程的几种状态
线程池的理解
你认为线程重要的方面有哪些?(我把线程牵扯到的问题都说出来了)
2,IO流方面
复制mp3的流程(上机就写的这个,大爷的,我没咋练过。只记个大概。错误百出)
复制文件夹的流程(牵扯到递归的知识)
3,对反射机制的理解
9,你的性格的优点缺点,如果让你竞选班长还有组长,你选哪个?
你通过什么路径了解到的黑马?为啥要来黑马学习?
你做过什么职位在学校?
10,try-catch式的区别
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

进程至少有一个线程,而且不同的线程之间可以在进程范围内共享数据。

也就是说进程有自己独立的存储空间,而线程是和它所属的进程内的其他线程共享一个存储空间。

线程的使用可以使我们能够并行地处理foxmail等),你当然不希望它们在收取新邮件的时候,导致你连已经收下来的邮件都无法阅读,而只能等待收取邮件操作执行完毕。

这正是线程的意义所在。

实现线程的方式实现线程的方式有两种:1.继承ng.Thread,并重写它的run()方法,将线程的执行主体放入其中。

2. 实现ng.Runnable接口,实现它的run()方法,并将线程的执行主体放入其中。

这是继承Thread类实现线程的示例:[java]view plaincopyprint?1.public class ThreadTest extends Thread {<BR>public void run() {<BR>// 在这里编写线程执行的主体<BR>// do something<BR>}<BR>}这是实现Runnable接口实现多线程的示例:[java]view plaincopyprint?1.public class RunnableTest implements Runnable {<BR>public void run() {<BR>// 在这里编写线程执行的主体<BR>// do something<BR>}<BR>}这两种实现方式的区别并不大。

继承Thread类的方式实现起来较为简单,但是继承它的类就不能再继承别的类了,因此也就不能继承别的类的有用的方法了。

而使用是想Runnable接口的方式就不存在这个问题了,而且这种实现方式将线程主体和线程对象本身分离开来,逻辑上也较为清晰,所以推荐大家更多地采用这种方式。

如何启动线程我们通过以上两种方式实现了一个线程之后,线程的实例并没有被创建,因此它们也并没有被运行。

我们要启动一个线程,必须调用方法来启动它,这个方法就是Thread类的start()方法,而不是run()方法(既不是我们继承Thread类重写的run()方法,也不是实现Runnable接口的run()方法)。

run()方法中包含的是线程的主体,也就是这个线程被启动后将要运行的代码,它跟线程的启动没有任何关系。

上面两种实现线程的方式在启动时会有所不同。

继承Thread类的启动方式:[java]view plaincopyprint?1.public class ThreadStartTest {<BR>public static void main(String[] args){<BR>// 创建一个线程实例<BR>ThreadTest tt = new ThreadTest();<BR>// 启动线程<BR>tt.start();<BR>}<BR>}实现Runnable接口的启动方式:[java]view plaincopyprint?1.public class RunnableStartTest {<BR>public static void main(String[] args) {<BR>// 创建一个线程实例<BR>Thread t = new Thread(new RunnableTest());<BR>// 启动线程<BR>t.start();<BR>}<BR>}实际上这两种启动线程的方式原理是一样的。

首先都是调用本地方法启动一个线程,其次是在这个线程里执行目标对象的run()方法。

那么这个目标对象是什么呢?为了弄明白这个问题,我们来看看Thread类的run()方法的实现:[java]view plaincopyprint?1.public void run() {<BR>if (target != null) {<BR>target.run();<BR>}<BR>} 当我们采用实现Runnable接口的方式来实现线程的情况下,在调用new Thread(Runnable target)构造器这个实例的run()方法就被执行了。

当我们采用继承Thread的方式实现线程时,线程的这个run()方法被重写了,所以当线程启动时,执行的是这个对象自身的run()方法。

总结起来就一句话,线程类有一个Runnable 类型的target属性,它是线程启动后要执行的run()方法所属的主体,如果我们采用的是继承Thread类的方式,那么这个target就是线程对象自身,如果我们采用的是实现Runnable接口的方式,那么这个target就是实现了Runnable接口的类的实例。

线程的状态在Java 1.4及以下的版本中,每个线程都具有新建、可运行、阻塞、死亡四种状态,但是在Java 5.0及以上版本中,线程的状态被扩充为新建、可运行、阻塞、等待、定时等待、死亡六种。

线程的状态完全包含了一个线程从新建到运行,最后到结束的整个生命周期。

线程状态的具体信息如下:1.NEW(新建状态、初始化状态):线程对象已经被创建,但是还没有被启动时的状态。

这段时间就是在我们调用new命令之后,调用start()方法之前。

2. RUNNABLE(可运行状态、就绪状态):在我们调用了线程的start()方法之后线程所处的状态。

处于RUNNABLE状态的线程在JAVA虚拟机(JVM)上是运行着的,但是它可能还正在等待操作系统分配给它相应的运行资源以得以运行。

3. BLOCKED(阻塞状态、被中断运行):线程正在等待其它的线程释放同步锁,以进入一个同步块或者同步方法继续运行;或者它已经进入了某个同步块或同步方法,在运行的过程中它调用了某个对象继承自ng.Object的wait()方法,正在等待重新返回这个同步块或同步方法。

4. WAITING(等待状态):当前线程调用了ng.Object.wait()、ng.Thread.join()或者java.util.concurrent.locks.LockSupport.park()三个中的任意一个方法,正在等待另外一个线程执行某个操作。

比如一个线程调用了某个对象的wait()方法,正在等待其它线程调用这个对象的notify()或者notifyAll()(这两个方法同样是继承自Object类)方法来唤醒它;或者一个线程调用了另一个线程的join()(这个方法属于Thread类)方法,正在等待这个方法运行结束。

5. TIMED_WAITING(定时等待状态):当前线程调用了ng.Object.wait(long timeout)、ng.Thread.join(long millis)、java.util.concurrent.locks.LockSupport.packNanos(longnanos)、java.util.concurrent.locks.LockSupport.packUntil(long deadline)四个方法中的任意一个,进入等待状态,但是与WAITING状态不同的是,它有一个最大等待时间,即使等待的条件仍然没有满足,只要到了这个时间它就会自动醒来。

6. TERMINATED(死亡状态、终止状态):线程完成执行后的状态。

线程执行完run()方法中的全部代码,从该方法中退出,进入TERMINATED状态。

还有一种情况是run()在运行过程中抛出了一个异常,而这个异常没有被程序捕获,导致这个线程异常终止进入TERMINATED状态。

在Java5.0及以上版本中,线程的全部六种状态都以枚举类型的形式定义在ng.Thread类中了,代码如下:[java]view plaincopyprint?1.public enum State {<BR>NEW,<BR>RUNNABLE,<BR>BLOCKED,<BR>WAITING,<BR>TIMED_WAITING,<BR>TERMINATED;<BR>}sleep()和wait()的区别sleep()方法和wait()方法都成产生让当前运行的线程停止运行的效果,这是它们的共同点。

下面我们来详细说说它们的不同之处。

sleep()方法是本地方法,属于Thread类,它有两种定义:[java]view plaincopyprint?1.public static native void sleep(long millis) throws InterruptedException;<BR>public static void sleep(long millis, int nanos) throws InterruptedException {<BR>//other code<BR>}其中的参数millis代表毫秒数(千分之一秒),nanos代表纳秒数(十亿分之一秒)。

这两个方法都可以让调用它的线程沉睡(停止运行)指定的时间,到了这个时间,线程就会自动醒来,变为可运行状态(RUNNABLE),但这并不表示它马上就会被运行,因为线程调度机制恢复线程的运行也需要时间。

调用sleep()方法并不会让线程释放它所持有的同步锁;而且在这期间它也不会阻碍其它线程的运行。

上面的连个方法都声明抛出一个InterruptedException类型的异常,这是因为线程在sleep()期间,有可能被持有它的引用的其它线程调用它的interrupt()方法而中断。

中断一个线程会导致一个InterruptedException异常的产生,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。

为了更好地理解interrupt()效果,我们来看一下下面这个例子:[java]view plaincopyprint?1.public class InterruptTest {<BR>public static void main(String[] args) {<BR>Thread t = new Thread() {<BR>public void run() {<BR>try {<BR>System.out.println("我被执行了-在sleep()方法前");<BR>// 停止运行10分钟<BR>Thread.sleep(1000 * 60 * 60 * 10);<BR>System.out.println("我被执行了-在sleep()方法后");<BR>} catch (InterruptedException e) {<BR>System.out.println("我被执行了-在catch语句块中");<BR>}<BR>System.out.println("我被执行了-在try{}语句块后");<BR>}<BR>};<BR>// 启动线程<BR>t.start();<BR>// 在sleep()结束前中断它<BR>t.interrupt();<BR>}<BR>}运行结果:1.我被执行了-在sleep()方法前2. 我被执行了-在catch语句块中3. 我被执行了-在try{}语句块后wait()方法也是本地方法,属于Object类,有三个定义:[java]view plaincopyprint?1.public final void wait() throws InterruptedException {<BR>//do something<BR>}<BR>public final native void wait(long timeout) throws InterruptedException;<BR>public final void wait(long timeout, int nanos) throws InterruptedException {<BR>//do something<BR>}wari()和wait(long timeout,int nanos)方法都是基于wait(long timeout)方法实现的。

相关文档
最新文档