资源预览内容
第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
亲,该文档总共7页全部预览完了,如果喜欢就下载吧!
资源描述
Java多线程知识点整理基本概念多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务,通常,每一个任务称为一个线程,它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序。多进程与多线程的区别:每个进程拥有自己的一整套变量,而线程则共享数据。相关接口Runnable 方法 void run()可由Runnable对象构成Thread,不要调用Thread类或者Runable对象的run方法,直接调用run方法,只会执行同一个线程中的任务,而不会启动新的线程。应该调用Thread.start方法,这个方法将创建一个执行run方法的新线程。Callable方法 V call() throws Exception;与Runnable类似,但有返回值Future方法 V get() throwsV get(long timeout, TimeUnit unit) throws .Void cancle(boolean mayInterupt) /取消计算,如果已经开始根据参数判断是否中断boolean isCacelled()boolean isDone() / 还在计算返回false,完成计算返回true保存异步计算的结果,可以启动一个计算,将future对象交给某个线程,然后忘掉它,future对象的所有者在结果计算好之后就可以获得它。第一个get方法的调用被阻塞,直到计算完成。如果在计算完成之前,第二个方法的调用超时,抛出一个timeoutException异常,如果运行该计算的线程被中断,两个方法都将抛出interruptedException,如果计算已经完成,那么get方法立即返回。FutureTask 包装器是一种非常便利的机制,可将Callable转换成future和Runnable,它同时实现二者的接口Callalbe myComputation = 。;FutureTask task = new FutureTask(myComputation );Thread t = new Thread(task);t.start();.V result = task.get();线程的状态要获得一个线程的状态,调用getState方法新生:当用new操作创建一个新线程时,该线程还没有开始运行,这意味着它的状态是新生。可运行:一旦调用start方法,线程处于runnable状态,记住在任何时刻,一个可运行的线程可能正在运行也可能没有运行阻塞/等待/计时等待:当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少的资源,直到线程调度器重新激活它。1.当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态,当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程将变成非阻塞状态2.当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用object.wait方法或者thread.join方法,或者等待lock或condition时就会出现这种情况3.有几个方法有一个超时参数,调用它们导致线程进入计时等待状态,这一状态将一直保持到超时期满,或者接收到适当的通知。终止:两个原因导致终止1.因为run方法正常退出而自然死亡 (当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时)2.因为一个没有捕获的异常终止了run方法而意外死亡没有一个状态叫做中断,中断方法interrupt只是用来申请,当调用该方法时,线程的中断状态被置位。每个线程都应该不时地检查这个标志,以判断线程是否被中断。如果线程被阻塞,就无法检测中断状态。当一个被阻塞的线程(调用sleep或者wait)上调用interrupt方法时,阻塞调用将会被InterruptedException异常中断。被中断的线程可以决定如何响应中断。如果在中断状态被置位时调用sleep方法,它不会休眠,相反,它将清除这一状态并抛出InterruptedException。因此如果你的循环调用sleep,不会检测中断状态,应捕获InterruptException异常线程的属性优先级:每一个线程有一个优先级,默认情况下,一个线程继承他的父线程的优先级。每当线程调度器有机会选择新线程时,它首先选择具有较高优先级的线程。Yield 方法导致当前执行线程处于让步状态,如果有其它的可运行线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调用。守护线程:setDaemon(true)可将线程转换为守护线程。守护线程应该永远不去访问固定资源,如文件,数据库,因为它会在任何时刻甚至在一个操作的中间发生中断。同步锁对象ReentrantLock结构: myLock.lock();try finally myLock.unlock(); .Lock myLock= new ReentrantLock();这一结构确保任何时刻,只有一个线程进入临界区,一旦一个线程封锁锁对象,其他任何线程都无法通过lock语句,当其他线程调用locka时,它们被阻塞,直到第一个线程释放锁对象。锁是可重入的,因为线程可以重复地获得已经持有的锁,锁保持一个持有计数来跟踪对lock方法的嵌套调用,线程在每一次调用lock都要调用unlock来释放锁。条件对象结构:myLock.lock();trywhile(! Ok to proceed) myCondition.await(); /当前线程被阻塞,并放弃了锁,进入该条件的等待集do thingsmyCondition.signalAll(); /解除因为这一条件而等待的所有线程,这些线程竞争后,被激活的线程从阻塞点开始执行程序finally myLock.unlock(); .Lock myLock= new ReentrantLock();Condition myCondition =myLock.newCondition();一个锁对象可以有一个或多个相关的条件对象。synchronized关键字结构:public synchronized void method()while(! Ok to procee)wait();do thingsnotifyAll();Java中的每一个对象都一个内部锁,如果一个方法用synchronized 声明,那么对象的锁将保护整个方法,也就是说,要调用该方法,线程必须获得内部的对象锁。内部对象锁只有一个相关条件,wait方法放置一个线程到等待集中,nogifyAll方法解除等待线程的阻塞状态相当于condition中的await和signalAll将静态方法声明为synchronized 也是合法的,如果调用这种方法,该方法获得相关类对象的内部锁,因此没有其他线程可以调用同一个类的这个或任何其他的同步静态方法。同步阻塞结构:synchronized(obj) 。Object obj = new Object();Volatile域结构: public boolean isDone()return done;public void setDone()done = true;private volatile boolean done;volatile关键字为实例域的同步访问提供了一种免锁机制,如果声明一个域为volatile,那么编译器和虚拟机就知道该域是可能被另一个线程并发更新的。volatile变量不能提供原子性 例如:public void flipdone() done = !done ; /not atomic 不能确保改变域中的值在这样一种非常简单的情况下,可以使用java.util.concurrent.atomic中提供的包装器类,用于原子的整数,浮点数,数组等。该类有get和set方法,确保是原子的。该实现使用有效的机器指令,在不使用锁的情况下确保原子性。锁测试与超时tryLock试图申请一个锁,在成功获得锁后返回true,否则立即返回false,而且线程可以立即离开做其他事情。调用tryLock时可使用超时参数。lock方法不能被中断,如果出现死锁,lock方法将无法终止。然而如果调用带超时参数的tryLock,那么如果线程在等待期间被中断,将抛出InterruptedException,将允许打破死锁。lockInterruptlibly相当于一个超时设为无限的tryLock方法在等待一个条件await时,也可以设置超时读/写锁ReentrantReadWriteLock结构: private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock ();private Lock readLock = rwl.readLock();private Lock writeLock = rwl.writeLock();readLock:得到一个可以被多个读操作共用的读锁,但会排斥所有写操作writeLock:得到一个写锁,排斥所有其他所有读操作和写操作。阻塞队列对于许多线程问题,可以通过使用一个或多个队列以优雅的且安全的方式将其形式化。生产者线程向队列插入元素,消费者线程则取出它们。使用队列,可以安全地从一个线程向另一个线程传递数据。在协调多个线程之间的合作时,阻塞队列是一个有用的工具。阻塞队列的方法分为3类:1.put和take:当试图向满的队列中体添加,或从空的队列中移出元素时,导致线程阻塞。用于将队列当做线程的管理工具来使用。2.add,remove和element,当试图向满的队列中体添加,或从空的队列中移出元素时抛出异常。3.offer,poll和peek,当试图向满的队列中体添加,或从空的队列中移出元素时如果不能完成任务,只是给出一个错误提示(返回null),而不会抛出异常。阻塞队列的几个变种:1.LinkedBlockingQueue : 没有上边界2.ArrayBlockingQueue :构造时需要指定容量3.priorityBlockingQueue:是一个带优先级的队列,而不是先进先出队列4.DelayQueue:包含实现Delayed接口的对象线程安全的集合阻塞队列也是线程安全的集合。其它集合:1.ConcurrentHashMap : 有相应的方法用于原子性的关联插入以及关联删除 (散列映像表)2.ConcurrentSkipListSet : 有序映像表3.ConcurrentLinkedQueue : 无边界非阻塞队列4.ConcurrentSkipListMap: 有相应的方法用于原子性的关联插入以及关联删除CopyOnWriteArrayList 和 copyOnWriteArraySet 是线程安全的集合。其中所有的修改线程对底层数组进行复制。如果在集合上进行迭代的线程超过修改的线程数,这样的安排是很有用的。当构建一个迭代器的时候,它包含一个对当前数组的引用,如果数组后来被修改了,迭代器仍然引用旧数组。Vector和HashTable是线程安全的,但后被弃用,取而代之的是ArrayList和HashMap,它们不是线程安全的。任何集合类通过使用同步包
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号