`
iamzhongyong
  • 浏览: 805474 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

【原】java线程温故

    博客分类:
  • java
 
阅读更多

java线程相关的东西一直处于模糊的状态,现在写篇文章整理一下,从头理一下一些概念。

---------------------------------------------------------------------------------

自己目前的一些理解:

(1)java的线程机制是一套java中最底层的代码实现,目前看核心的代码有两个,一个是Runnable接口,一个是Thread类。

(2)在编写多线程并发程序是,使用底层的api来进行写代码,稍有不慎,或者对于线程机制了解不是特别深入,很容易出现死锁、饥饿锁、线程安全等问题。

(3)java.util.courrent包对于并发编程进行了封装,通过简单的代码就可以实现并发程序,屏蔽掉了对于线程底层的一些操作,是并发代码变得简单安全。

 

--------------------------------------------------------------------------------

 

线程的各个状态已经状态之间的变化

 

        NEW:线程被创建,但是没有start

 

        RUNNABLE:线程可运行,已经在JVM的虚拟机中,但是等待其他的资源,例如CPU处理器

 

        BLOCKED:线程阻塞

 

        WAITING:线程等待

 

        TIMED_WAITING:等待具体的时间,例如等待10Min

 

        TERMINATED:线程终止

 

上面的是Thread类中对于状态的各个枚举类型,但是描述的时候,稍微有点出入,可能是为了更加方便理解吧。

 

 

 

 

 

--------------------------------------------------------------------------------

 

关于守护进程

 

  1. 守护线程通常由虚拟机自己使用,比如垃圾收集器的线程;
  2. Java程序可以把它任何创建的线程标记为守护线程;但必须在线程运行前设置
  3. Java初始线程(即开始于main方法的线程)是非守护线程;
  4. 只要还有任何非守护线程在运行,那么这个Java程序也在运行,即这个JVM实例还存活着;当JVM中的所有非守护线程都终止时,JVM实例将自动退出;

理解上面的几个特点,可以运行一下下面的代码:

 

public class Daemon {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		ThreadTest thread = new ThreadTest();
		thread.setDaemon(true);
		thread.start();
		 for (int i = 0; i < 10; i++) {
	            System.out.println("Main thread: " + i);
	            Thread.sleep(1000);
	     }
	}
}



	class ThreadTest extends Thread{
		private int index = 0;
		 
	    @Override
	    public void run() {
	        while (index < 100) {
	            System.out.println("========= Daemon thread: " + index++);
	            try {
	                Thread.sleep(1000);
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	}

--------------------------------------------------------------------------------

对于一些概念的解释:

 

 
1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。

Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
static int MAX_PRIORITY
线程可以具有的最高优先级,取值为10。
static int MIN_PRIORITY
线程可以具有的最低优先级,取值为1。
static int NORM_PRIORITY
分配给线程的默认优先级,取值为5。

Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。

每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。

2、线程睡眠:Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好。

3、线程等待:Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。这个两个唤醒方法也是Object类中的方法,行为等价于调用 wait(0) 一样。

4、线程让步:Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。

5、线程加入:join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。

6、线程唤醒:Object类中的notify()方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。类似的方法还有一个notifyAll(),唤醒在此对象监视器上等待的所有线程。

 

 

 -------------------------------------------------------------------------------

关于volatile

 

 

java也提供了其他的选择,一种同步的弱形式,volatile变量。它确保对一个

变量的更新以可预见的方式告诉其他的线程。当一个域声明为volatile类型后

编译器与运行时会监视这个变量,他是共享的,而且对他的操纵不会与其他的内存操作一起被排序。

 

volatile变量不会缓存在寄存器或者其他地方,所以去读一个volatile类型的变量,总会返回由一个线程写入的最新值。

 

访问volatile变量不会加锁,也就不会引起执行线程的阻塞,这样使得volatile变量相对于synchroized而言,是一个轻量级的同步机制。

 

-------------------------------------------------------------------------------

 

 

大多数并发程序是围绕执行任务进行管理的。所谓任务就是抽象、离散的工作单元。

无限制出阿健线程的缺点:

(1)线程生命周期的开销

(2)资源消耗量,活动线程会消耗系统资源,尤其是内存,如果可运行的线程数多

于可用的处理器数,线程将会关闭。大量空闲线程占用更多内存,给立即回收器带来压力,而且大量线程在竞争CPU资源时,还会其他性能开销。

(3)稳定性

 

--------------------------------------------------------------------------------

 

Executor只是个简单的接口,单它却为一个灵活而强大的框架创造了基础,这个框架可以异步的执行任务,而且支持很多不同类型的任务执行策略。

它还为任务提交和任务执行之间的解耦提供了标准的方法,为使用Runnable描述任务提供了通用的方式。

Executor基于生产者-消费者模式。提交任务的执行者是生产者,执行任务的是消费者。如果要在程序中实现一个生产者-消费者设计,使用Executor通常是最简单的方式。

 

 

可以通过Executeors中的静态工厂方法来创建一个线程池。

 

newFixedThreadPool创建一个定长的线程池,没得哪个提交一个任务就创建一个线程,知道达到吃的最大长度,这时候线程会保持长度不在变化。

 

newCachedThreadPool 创建一个可缓存的线程池,如果当线程池的长度超过了处理的需要,它可以灵活的回收空闲的线程,当需求增加时,它可以灵活的增加新的线程,而并不会对持的长度做任何限制。

 

newSingleThreadExecutor 创建一个单线程化的executor,它只创建唯一的工作线程来维护任务,如果这个线程异常结束,会有两一个取代它。executor会保证任务依照任务所规定的顺序执行。

 

newScheduleThreadPool创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于TImer

 

 

 

 

---------------------------------------------------------------------------------

java.util.courrent包类关系介绍一下:

通过下图,对于并发中的几个类关系会比较明确。

 

 

 

 

 

 

 

 

 

 

 

后续:对于courrent中的各个方法,以例子的形式继续给出。

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    java多线程设计模式详解(PDF及源码)

    本书浅显易懂的介绍了JAVA线程相关的设计模式,通过程序范例和UML图示来一一解说,书中代码的重要部分加了标注以使读者更加容易理解,再加上图文并茂,对于初学者还是程序设计高手来说,这都是一本学习和认识JAVA...

    java多线程设计模式及源码

    多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍JAVA线程相关的设计模式概念,并且通过实际的JAVA程序范例和UML图示来一一解说,书中有代码的重要部分加上标注使读者更加容易...

    java多线程同步例子

    java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料

    《Java多线程设计模式》附源码中文教程 (PDF)

    本书浅显易懂的介绍了JAVA线程相关的设计模式,通过程序范例和UML图示来一一解说,书中代码的重要部分加了标注以使读者更加容易理解,再加上图文并茂,对于初学者还是程序设计高手来说,这都是一本学习和认识JAVA...

    JAVA多线程设计模式(带完整书签清晰扫描版)

    《JAVA多线程设计模式》中包含JAVA线程的介绍导读,12个重要的线程设计模式和全书总结以及丰富的附录内容。每一章相关线程设计模式的介绍,都举一反三使读者学习更有效率。最后附上练习问题,让读者可以温故而知新,...

    java多线程设计模式详解part2

    多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍JAVA线程相关的设计模式概念,并且通过实际的JAVA程序范例和UML图示来一一解说,书中有代码的重要部分加上标注使读者更加容易...

    java多线程设计模式详解part1

    多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍JAVA线程相关的设计模式概念,并且通过实际的JAVA程序范例和UML图示来一一解说,书中有代码的重要部分加上标注使读者更加容易...

    java多线程设计模式

    《JAVA多线程设计模式》中包含JAVA线程的介绍导读,12个重要的线程设计模式和全书总结以及丰富的附录内容。每一章相关线程设计模式的介绍,都举一反三使读者学习更有效率。最后附上练习问题,让读者可以温故而知新,...

    java面经 Linux 系统 数据结构 设计模式 快速入门

    java面经,面试java会遇到的问题,温故而知新!里面共有14章,第一章基础,第二章集合类,第三章锁,第四章多线程,第五章ssh/ssm框架,第六章内存和垃圾回收,第七章juc包,第八章数据库,第九章网络,第十章操作...

    学习java的心得体会 (2).docx

    阶段性地做一下专题总结,温故而知新,养成阶段性地做专题总结的习惯,例如你这个月学习或在做与多线程有关的模块或项目。 九、要有持之以恒的精神 要学好任何一门技术,需要有持之以恒精益求精的精神,特别是学...

    JavaSE 通俗易懂 (基础+高级+多线程+面试题).html

    JavaSE全套总结,温故而知新,生动形象

    安桌toast用法小例

    本教程将针对Android `Toast`的使用进行详细讲解,非常适合初学者入门,即便是有经验的开发者,温故而知新也是必要的。 首先,我们来了解如何创建一个基本的`Toast`。在Android中,`Toast`类提供了创建和显示消息的...

Global site tag (gtag.js) - Google Analytics