有域名怎么做公司网站,深圳市建设管理中心网站首页,成都网站建设前50强,网站备案未注销 影响1#xff0c;什么是线程#xff1f;线程是操作系统能够进行运算调度的最小单位#xff0c;它被包含在进程之中#xff0c;是进程中的实际运作单位。程序员可以通过它进行多处理器编程#xff0c;你可以使用多线程对运算密集型任务提速。比如#xff0c;如果一个线程完成一…1什么是线程线程是操作系统能够进行运算调度的最小单位它被包含在进程之中是进程中的实际运作单位。程序员可以通过它进行多处理器编程你可以使用多线程对运算密集型任务提速。比如如果一个线程完成一个任务要100毫秒那么用十个线程完成改任务只需10毫秒。2线程和进程有什么区别线程是进程的子集一个进程可以有很多线程每条线程并行执行不同的任务。不同的进程使用不同的内存空间而所有的线程共享一片相同的内存空间。每个线程都拥有单独的栈内存用来存储本地数据。3如何在Java中实现线程两种方式java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。4Java 关键字volatile 与 synchronized 作用与区别1volatile它所修饰的变量不保留拷贝直接访问主内存中的。在Java内存模型中有main memory每个线程也有自己的memory (例如寄存器)。为了性能一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变 量在某个瞬间在一个线程的memory中的值可能与另外一个线程memory中的值或者main memory中的值不一致的情况。 一个变量声明为volatile就意味着这个变量是随时会被其他线程修改的因此不能将它cache在线程memory中。2synchronized当它用来修饰一个方法或者一个代码块的时候能够保证在同一时刻最多只有一个线程执行该段代码。一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。二、然而当一个线程访问object的一个synchronized(this)同步代码块时另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。三、尤其关键的是当一个线程访问object的一个synchronized(this)同步代码块时其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。四、当一个线程访问object的一个synchronized(this)同步代码块时它就获得了这个object的对象锁。结果其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。五、以上规则对其它对象锁同样适用.5有哪些不同的线程生命周期当我们在Java程序中新建一个线程时它的状态是New。当我们调用线程的start()方法时状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间并且讲它们的状态改变为Running。其他的线程状态还有WaitingBlocked 和Dead。6你对线程优先级的理解是什么每一个线程都是有优先级的一般来说高优先级的线程在运行时会具有优先权但这依赖于线程调度的实现这个实现是和操作系统相关的(OS dependent)。我们可以定义线程的优先级但是这并不能保证高优先级的线程会在低优先级的线程前执行。线程优先级是一个int变量(从1-10)1代表最低优先级10代表最高优先级。7什么是死锁(Deadlock)如何分析和避免死锁死锁是指两个以上的线程永远阻塞的情况这种情况产生至少需要两个以上的线程和两个以上的资源。分析死锁我们需要查看Java应用程序的线程转储。我们需要找出那些状态为BLOCKED的线程和他们等待的资源。每个资源都有一个唯一的id用这个id我们可以找出哪些线程已经拥有了它的对象锁。避免嵌套锁只在需要的地方使用锁和避免无限期等待是避免死锁的通常办法。8什么是线程安全Vector是一个线程安全类吗如果你的代码所在的进程中有多个线程在同时运行而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的而且其他的变量的值也和预期的是一样的就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。9Java中如何停止一个线程Java提供了很丰富的API但没有为停止线程提供API。JDK 1.0本来有一些像stop(), suspend() 和 resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了之后Java API的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当run() 或者 call() 方法执行完的时候线程会自动结束,如果要手动结束一个线程你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程10什么是ThreadLocal?ThreadLocal用于创建线程的本地变量我们知道一个对象的所有线程会共享它的全局变量所以这些变量不是线程安全的我们可以使用同步技术。但是当我们不想使用同步的时候我们可以选择ThreadLocal变量。每个线程都会拥有他们自己的Thread变量它们可以使用get()\set()方法去获取他们的默认值或者在线程内部改变他们的值。ThreadLocal实例通常是希望它们同线程状态关联起来是private static属性。11Sleep()、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()类似只是前者需要获取对象锁。12什么是线程饿死什么是活锁当所有线程阻塞或者由于需要的资源无效而不能处理不存在非阻塞线程使资源可用。JavaAPI中线程活锁可能发生在以下情形1当所有线程在程序中执行Object.wait(0)参数为0的wait方法。程序将发生活锁直到在相应的对象上有线程调用Object.notify()或者Object.notifyAll()。2当所有线程卡在无限循环中。13什么是Java Timer类如何创建一个有特定时间间隔的任务java.util.Timer是一个工具类可以用于安排一个线程在未来的某个特定时间执行。Timer类可以用安排一次性任务或者周期任务。java.util.TimerTask是一个实现了Runnable接口的抽象类我们需要去继承这个类来创建我们自己的定时任务并使用Timer去安排它的执行。14Java中的同步集合与并发集合有什么区别同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合不过并发集合的可扩展性更高。在Java1.5之前程序员们只有同步集合来用且在多线程并发的时候会导致争用阻碍了系统的扩展性。Java5介绍了并发集合像ConcurrentHashMap不仅提供线程安全还用锁分离和 内部分区等现代技术提高了可扩展性。15同步方法和同步块哪个是更好的选择同步块是更好的选择因为它不会锁住整个对象(当然你也可以让它锁住整个对象)。同步方法会锁住整个对象哪怕这个类中有多个不相关联的同步块这通常会导致他们停止执行并需要等待获得这个对象上的锁。16什么是线程池 为什么要使用它创建线程要花费昂贵的资源和时间如果任务来了才创建线程那么响应时间会变长而且一个进程能创建的线程数有限。为了避免这些问题在程序启动的时候就创建若干线程来响应处理它们被称为线程池里面的线程叫工作线程。从JDK1.5开始Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池每次处理一个任务数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)。17Java中invokeAndWait 和 invokeLater有什么区别这两个方法是Swing API 提供给Java开发者用来从当前线程而不是事件派发线程更新GUI组件用的。InvokeAndWait()同步更新GUI组件比如一个进度条一旦进度更新了进度条也要做出相应改变。如果进度被多个线程跟踪那么就调用invokeAndWait()方法请求事件派发线程对组件进行相应更新。而invokeLater()方法是异步调用更新组件的。18多线程中的忙循环是什么?忙循环就是程序员用循环让一个线程等待不像传统方法wait(), sleep() 或 yield() 它们都放弃了CPU控制而忙循环不会放弃CPU它就是在运行一个空循环。这么做的目的是为了保留CPU缓存。在多核系统中一个等待线程醒来的时候可能会在另一个内核运行这样会重建缓存。为了避免重建缓存和减少等待重建的时间就可以使用它了。19Java内存模型是什么Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一个线程所做的变动能被其它线程可见提供了保证它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如先行发生关系确保了线程内的代码能够按先后顺序执行这被称为程序次序规则。对于同一个锁一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前也叫做管程锁定规则。前一个对volatile的写操作在后一个volatile的读操作之前也叫volatile变量规则。一个线程内的任何操作必需在这个线程的start()调用之后也叫作线程启动规则。一个线程的所有操作都会在线程终止之前线程终止规则。一个对象的终结操作必需在这个对象构造完成之后也叫对象终结规则。可传递性20Java中interrupted 和isInterruptedd方法的区别interrupted() 和 isInterrupted()的主要区别是前者会将中断状态清除而后者不会。Java多线程的中断机制是用内部标识来实现的调用Thread.interrupt()来中断一个线程就会设置中断标识为true。当中断线程调用静态方法Thread.interrupted()来检查中断状态时中断状态会被清零。非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛出InterruptedException异常的方法都会将中断状态清零。无论如何一个线程的中断状态都有可能被其它线程调用中断来改变。21Java中的同步集合与并发集合有什么区别同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合不过并发集合的可扩展性更高。在Java1.5之前程序员们只有同步集合来用且在多线程并发的时候会导致争用阻碍了系统的扩展性。Java5介绍了并发集合像ConcurrentHashMap不仅提供线程安全还用锁分离和内部分区等现代技术提高了可扩展性。不管是同步集合还是并发集合他们都支持线程安全他们之间主要的区别体现在性能和可扩展性还有他们如何实现的线程安全上。同步HashMap, Hashtable, HashSet, Vector, ArrayList 相比他们并发的实现(ConcurrentHashMap, CopyOnWriteArrayList, CopyOnWriteHashSet)会慢得多。造成如此慢的主要原因是锁 同步集合会把整个Map或List锁起来而并发集合不会。并发集合实现线程安全是通过使用先进的和成熟的技术像锁剥离。比如ConcurrentHashMap 会把整个Map 划分成几个片段只对相关的几个片段上锁同时允许多线程访问其他未上锁的片段。同样的CopyOnWriteArrayList 允许多个线程以非同步的方式读当有线程写的时候它会将整个List复制一个副本给它。如果在读多写少这种对并发集合有利的条件下使用并发集合这会比使用同步集合更具有可伸缩性。22什么是线程池 为什么要使用它创建线程要花费昂贵的资源和时间如果任务来了才创建线程那么响应时间会变长而且一个进程能创建的线程数有限。为了避免这些问题在程序启动的时候就创建若干线程来响应处理它们被称为线程池里面的线程叫工作线程。从JDK1.5开始Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池每次处理一个任务数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)线程池的作用就是在调用线程的时候初始化一定数量的线程有线程过来的时候先检测初始化的线程还有空的没有没有就再看当前运行中的线程数是不是已经达到了最大数如果没有就新分配一个线程去处理。就像餐馆中吃饭一样从里面叫一个服务员出来但如果已经达到了最大数就相当于服务员已经用尽了那没得办法另外的线程就只有等了直到有新的“服务员”为止。线程池的优点就是可以管理线程有一个高度中枢这样程序才不会乱保证系统不会因为大量的并发而因为资源不足挂掉。23Java中活锁和死锁有什么区别活锁一个线程通常会有会响应其他线程的活动。如果其他线程也会响应另一个线程的活动那么就有可能发生活锁。同死锁一样发生活锁的线程无法继续执行。然而线程并没有阻塞——他们在忙于响应对方无法恢复工作。这就相当于两个在走廊相遇的人甲向他自己的左边靠想让乙过去而乙向他的右边靠想让甲过去。可见他们阻塞了对方。甲向他的右边靠而乙向他的左边靠他们还是阻塞了对方。死锁两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候死锁会让你的程序挂起无法完成任务。24如何避免死锁死锁的发生必须满足以下四个条件互斥条件一个资源每次只能被一个进程使用。请求与保持条件一个进程因请求资源而阻塞时对已获得的资源保持不放。不剥夺条件进程已获得的资源在末使用完之前不能强行剥夺。循环等待条件若干进程之间形成一种头尾相接的循环等待资源关系。三种用于避免死锁的技术加锁顺序(线程按照一定的顺序加锁)加锁时限(线程尝试获取锁的时候加上一定的时限超过时限则放弃对该锁的请求并释放自己占有的锁)死锁检测25notify()和notifyAll()有什么区别1notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。2void notify(): 唤醒一个正在等待该对象的线程。3void notifyAll(): 唤醒所有正在等待该对象的线程。两者的最大区别在于notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态变成等待该对象上的锁一旦该对象被解锁他们就会去竞争。notify他只是选择一个wait状态线程进行通知并使它获得该对象上的锁但不惊动其他同样在等待被该对象notify的线程们当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句即便该对象已经空闲其他wait状态等待的线程由于没有得到该对象的通知继续处在wait状态直到这个对象发出一个notify或notifyAll它们等待的是被notify或notifyAll而不是锁。26什么是可重入锁(ReentrantLock)Java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象它允许把锁定的实现作为Java 类而不是作为语言的特性来实现。这就为Lock 的多种实现留下了空间各种实现可能有不同的调度算法、性能特性或者锁定语义。 ReentrantLock 类实现了Lock 它拥有与synchronized 相同的并发性和内存语义但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外它还提供了在激烈争用情况下更佳的性能。(换句话说当许多线程都想访问共享资源时JVM可以花更少的时候来调度线程把更多时间用在执行线程上。)Reentrant 锁意味着什么呢简单来说它有一个与锁相关的获取计数器如果拥有锁的某个线程再次得到锁那么获取计数器就加1然后锁需要被释放两次才能获得真正释放。这模仿了synchronized 的语义如果线程进入由线程已经拥有的监控器保护的synchronized 块就允许线程继续进行当线程退出第二个(或者后续)synchronized块的时候不释放锁只有线程退出它进入的监控器保护的第一个synchronized 块时才释放锁。27读写锁可以用于什么应用场景读写锁可以用于 “多读少写” 的场景读写锁支持多个读操作并发执行写操作只能由一个线程来操作ReadWriteLock对向数据结构相对不频繁地写入但是有多个任务要经常读取这个数据结构的这类情况进行了优化。ReadWriteLock使得你可以同时有多个读取者只要它们都不试图写入即可。如果写锁已经被其他任务持有那么任何读取者都不能访问直至这个写锁被释放为止。ReadWriteLock 对程序性能的提高主要受制于如下几个因素1数据被读取的频率与被修改的频率相比较的结果。2读取和写入的时间3有多少线程竞争4是否在多处理机器上运行以上就是本文的全部内容希望对大家的学习有所帮助也希望大家多多支持脚本之家。