首页 > 代码库 > Java学习之多线程一

Java学习之多线程一

1.进程与线程的关系
一个程序运行后至少有一个进程,一个进程中可以包含多个线程
2.多线程两种实现方式
A:实现线程程序继承Thread

/**
 * 定义子类,继承Thread
 * 重写run()
 * @author vanguard
 *
 */
public class SubThread extends Thread {
    public void run() {
        for(int i = 0; i < 50; i++) {
            System.out.println("run..." + i);
        }
    }
}
 1 /**
 2  * 多线程
 3  * 创建和启动一个线程
 4  *    创建Thread子类对象
 5  *    子类对象调用方法start()      
 6  *    让线程程序执行,JVM调用线程中的run
 7  * @author vanguard
 8  *
 9  */
10 public class ThreadDemo01 {
11     public static void main(String[] args) {
12         //创建Thread子类对象
13         SubThread st = new SubThread();
14         //子类对象调用start()
15         st.start();
16         for(int i = 0; i < 50; i++) {
17             System.out.println("main..." + i);
18         }
19     }
20 }

 


B:实现线程的另一种方式实现Runnable接口

/**
 * 实现Runnable接口
 * 重写run()
 * @author vanguard
 *
 */
public class SubRunnable implements Runnable {
    public void run() {
        for(int i = 0; i < 50; i++) {
            System.out.println("run..." + i);
        }
    }
}
/**
 * 实现接口方式的线程
 *     创建Thread对象,在构造方法中传递Ruannable接口实现类对象
 *    调用Thread的start()
 * @author vanguard
 *
 */
public class ThreadDemo01 {
    public static void main(String[] args) {
        SubRunnable sr = new SubRunnable();
        Thread t = new Thread(sr);
        t.start();
        for(int i = 0; i < 50; i++) {
            System.out.println("main..." + i);
        }
    }
}

 


3.多线程两种实现方式的区别
  实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。
  继承Thread类,线程对象和线程任务耦合在一起。
  一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。
  实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。
  (降低紧密性或者依赖性,创建线程和执行任务不绑定)
4.线程池的原理
  1).在java中,如果每个请求到达就创建一个新线程,开销是相当大的。
  2).在实际使用中,创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。
  3).除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。
  如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。
  为了防止资源不足,需要采取一些办法来限制任何给定时刻处理的请求数目,尽可能减少创建和销毁线程的次数,
  特别是一些资源耗费比较大的线程的创建和销毁,尽量利用已有对象来进行服务。
  线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重复使用线程,
  线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,
  所以消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使用应用程序响应更快。
  另外,通过适当的调整线程中的线程数目可以防止出现资源不足的情况。
4.线程的生命周期 

  新建(new Thread)
  当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。

  例如:Thread  t1=new Thread();

 

  就绪(runnable)
  线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

 

  运行(running)
  线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

 

  死亡(dead)
  当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

 

  自然终止:正常运行run()方法后终止

 

  异常终止:调用stop()方法让一个线程终止运行

 

  堵塞(blocked)
  由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

 

  正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

 

  正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

 

  被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)

 

Java学习之多线程一