首页 > 代码库 > 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学习之多线程一