• java线程


    看到一篇讲的不错的java线程的文章 引用之:http://www.cnblogs.com/yanng/articles/2162124.html

    如何创建一个线程?  
      1、 扩展java.lang.Thread类 
      2、 实现Runnable接口 
      Thread类代表线程类,它的两个最主要的方法是: 
      run()——包含线程运行时所执行的代码 
      Start()——用于启动线程 

    线程特性
      一个线程只能被启动一次。第二次启动时将会抛出java.lang.IllegalThreadExcetpion异常 
    线程间状态的转换
      新建状态:用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 
      就绪状态:当一个线程创建了以后,其他的线程调用了它的start()方法,该线程就进入了就绪状态。处于这个状态线程位于可运行池中,等待获得CPU的使用权 
      运行状态:处于这个状态的线程占用CPU,执行程序的代码 
      阻塞状态:当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到运行状态。 
      阻塞状态分为三种情况: 
        1、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放    到这个对象的等待池中
        2、 位于对象锁中的阻塞状态,当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被      其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。 
      3、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会   进入这个状态中。 
    如果希望明确地让一个线程给另外一个线程运行的机会
      1、 调整各个线程的优先级 
      2、 让处于运行状态的线程调用Thread.sleep()方法 
      3、 让处于运行状态的线程调用Thread.yield()方法 
      4、 让处于运行状态的线程调用另一个线程的join()方法 
      调整各个线程的优先级 
      Thread类的setPriority(int)和getPriority()方法分别用来设置优先级和读取优先级。 
      如果希望程序能够移值到各个操作系统中,应该确保在设置线程的优先级时,只使用MAX_PRIORITY、NORM_PRIORITY、MIN_PRIORITY这3个优先级。 
      线程睡眠:当线程在运行中执行了sleep()方法时,它就会放弃CPU,转到阻塞状态。 
      线程让步:当线程在运行中执行了Thread类的yield()静态方法时,如果此时具有相同优先级的其它线程处于就绪状态,那么yield()方法将把当前运行的线程放到运行池中并使另一个线程运行。如果没有相同优先级的可运行线程,则yield()方法什么也不做。 
      Sleep()方法和yield()方法都是Thread类的静态方法,都会使当前处于运行状态的线程放弃CPU,把运行机会让给别的线程,两者的区别在于: 

      1、sleep()方法会给其他线程运行的机会,而不考虑其他线程的优先级,因此会给较低线程一个运行的机会;yield()方法只会给相同优先级或者更高优先级的线程一个运行的机会。 

      2、当线程执行了sleep(long millis)方法后,将转到阻塞状态,参数millis指定睡眠时间;当线程执行了yield()方法后,将转到就绪状态。 
          3、sleep()方法声明抛出InterruptedException异常,而yield()方法没有声明抛出任何异常 
          4、sleep()方法比yield()方法具有更好的移植性 
      等待其它线程的结束:join() 
              当前运行的线程可以调用另一个线程的 join()方法,当前运行的线程将转到阻塞状态,直到另一个线程运行结束,它才恢复运行。 
    线程的同步 
      原子操作:由一组相关的操作完成,这些操作可能会操纵与其它的线程共享的资源,为了保证得到正确的运算结果,一个线程在执行原子操作其间,应该采取其他的措施使得其他的线程不能操纵共享资源。 
      同步代码块:为了保证每个线程能够正常执行原子操作,Java引入了同步机制,具体的做法是在代表原子操作的程序代码前加上synchronized标记,这样的代码被称为同步代码块。 
      同步锁:每个JAVA对象都有且只有一个同步锁,在任何时刻,最多只允许一个线程拥有这把锁。 
      当一个线程试图访问带有synchronized(this)标记的代码块时,必须获得 this关键字引用的对象的锁,在以下的两种情况下,本线程有着不同的命运。 
      1、 假如这个锁已经被其它的线程占用,JVM就会把这个线程放到本对象的锁池中。本线程进入阻塞状态。锁池中可能有很多的线程,等到其他的线程释放了锁,JVM就会从锁池中随机取出一个线程,使这个线程拥有锁,并且转到就绪状态。 
      2、 假如这个锁没有被其他线程占用,本线程会获得这把锁,开始执行同步代码块。 
      (一般情况下在执行同步代码块时不会释放同步锁,但也有特殊情况会释放对象锁 
    如在执行同步代码块时,遇到异常而导致线程终止,锁会被释放;在执行代码块时,执行了锁所属对象的wait()方法,这个线程会释放对象锁,进入对象的等待池中) 
      线程同步的特征: 
      1、 如果一个同步代码块和非同步代码块同时操作共享资源,仍然会造成对共享资源的竞争。因为当一个线程执行一个对象的同步代码块时,其他的线程仍然可以执行对象的非同步代码块。(所谓的线程之间保持同步,是指不同的线程在执行同一个对象的同步代码块时,因为要获得对象的同步锁而互相牵制) 
      2、 每个对象都有唯一的同步锁 
      3、 在静态方法前面可以使用synchronized修饰符。 
      4、 当一个线程开始执行同步代码块时,并不意味着必须以不间断的方式运行,进入同步代码块的线程可以执行Thread.sleep()或者执行Thread.yield()方法,此时它并不释放对象锁,只是把运行的机会让给其他的线程。 
      5、 Synchronized声明不会被继承,如果一个用synchronized修饰的方法被子类覆盖,那么子类中这个方法不在保持同步,除非用synchronized修饰。 
    线程安全的类: 
      1、 这个类的对象可以同时被多个线程安全的访问。 
      2、 每个线程都能正常的执行原子操作,得到正确的结果。 
      3、 在每个线程的原子操作都完成后,对象处于逻辑上合理的状态。 
    线程通信 
      Java.lang.Object类中提供了两个用于线程通信的方法 
      1、 wait():执行了该方法的线程释放对象的锁,JVM会把该线程放到对象的等待池中。该线程等待其它线程唤醒 
      2、 notify():执行该方法的线程唤醒在对象的等待池中等待的一个线程,JVM从对象的等待池中随机选择一个线程,把它转到对象的锁池中。

  • 相关阅读:
    fescar中文官网
    mybatis 中的 update 返回值你真的明白吗
    数据库读写分离搭建
    git 回退各种场景操作
    听说noip2015有幻方
    noi2015的回忆和教训
    bzoj4026
    bzoj4127
    bzoj2119
    关于fft的一点总结
  • 原文地址:https://www.cnblogs.com/fwycmengsoft/p/2263209.html
Copyright © 2020-2023  润新知