• 多线程编程


    进程的概念:一个正在运行的程序通常称为一个进程,每一个进程都已一个自己的独立内存空间,所以各个进程的内部数据和状态也都是完全独立的。

    线程的概念:线程存在于进程的内部,其中的每一个任务称之为一个线程,它是程序中最小的处理单位,并且启动后一般不受控制。这些线程可以共享一块内存空间。

    线程中常用的类及方法:

      Thread类

           public void start()   用于启动线程,调用Thread类对象上的 run() 方法;

             public void run()    用于写线程要执行的代码,继承Thread类后要重写该方法;

            public static void sleep(long millise) 用于让当前正在运行的线程休眠指定的时间;(单位为:毫秒)

      Runnable接口

            其中只定义了一个run()方法,用于写线程要执行的代码;

      Object类

           public final void wait()  使当前对象无限期的等待,直到其它的线程遇到 notify()或 notifyAll();

           public final void notify()   用于唤醒正在该对象上等待的一个线程,当前线程必须拥有对象的锁;

           public final void notifyAll()   与notify()类似,但是是唤醒所有等待的线程;

    创建线程的两中方法:

      1. 继承Thread类,重写run()方法;

        例:

     1 public class ThreadDemo {
     2 
     3     public static void main(String[] args) {
     4         Tread1 t1 = new Tread1(); // 实例化Thread子类的实例
     5         t1.start(); // 启动线程
     6     }
     7 }
     8 
     9 class Tread1 extends Thread { // 创建Thread子类
    10     @Override
    11     public void run() { // 重写run方法
    12 
    13     }
    14 }

      

      2. 实现Runnable接口,然后将该类的实例与Thread对象联系在一起;

        例:

     1 public class RunnableDemo {
     2 
     3     public static void main(String[] args) {
     4 
     5         // 实例化Runnable实现类的实例
     6         MyTest myTest = new MyTest();
     7 
     8         // 创建Thread对象,将Runnable实例传进去
     9         Thread t1 = new Thread(myTest);
    10 
    11         // 启动线程
    12         t1.start();
    13     }
    14 }
    15 
    16 class MyTest implements Runnable { // 创建Runnable实现类
    17     @Override
    18     public void run() { // 实现run方法
    19 
    20     }
    21 }

     两种创建方法的比较:

      1. Thread类也是实现了Runnable接口的;

      2. 使用Runnable接口可以将虚拟CPU(Thread类)与线程要完成的任务有效的分离,较好的体现了oop的设计原则;

      3. 使用Runnable接口可以避免Java单继承的局限。

       综上所述,使用Runnable接口要有利一些;

     

    线程间的状态转换图: 

    1新建(new):新创建了一个线程对象。

    2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

    3. 运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。

    4. 阻塞(blocked):当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片。 

    5. 等待池(wait pool):当线程调用wait()方法后会进入等待池(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。

    6.  锁池(lock pool)当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;

    7. 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

  • 相关阅读:
    The Tamworth Two chapter 2.4
    USACO Controlling Companies chapter 2.3 已跪
    非递归快排
    链表二路归并
    Money Systems chapter 2.3 dp
    #pragma pack与sizeof union
    快慢指针
    12
    11
    10
  • 原文地址:https://www.cnblogs.com/renchang/p/4457811.html
Copyright © 2020-2023  润新知