黑马程序员-----java线程学习与总结
2014-09-18 23:47
531 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1、线程的概念
Thread,是一个进程更加微观的一个对象。进程是OS任务调度的最基本单位。
独立性:线程不能独立存在,线程依赖于进程存在。
存储区域:进程中的数据存在堆栈中,线程的数据存在于寄存器中。
粒度:线程小,进程大。
2、Java中关于线程的API
线程的API包括一个java.lang.Thread类和一个接口java.lang.Runnable接口。
Runnable接口只有一个抽象run()方法。而Thread类实际上是对Runnable接口的实现。
Thread的方法大概分为3类:
获取线程信息方法:getName()/getPriority()
设置线程信息方法:
setName()/setPriority()
有关线程生命周期的方法
Sleep()/join()/interrupt()/interrupted()/isAlive()/run()/resume()/suspend()/start()
3、实现线程的方式
Thread():构造一个缺省线程类
Thread(String name):构造一个名称为name的线程类
Thread(Runnable r):构造由R实现的线程类
Thread(Runnable r,String name):构造由R实现,名称为name的线程。
我们定义线程类,核心机制重写run()方法,在run()方法中写线程的功能代码。
(1)自定义的类继承Thread类实现
第一步:定义run()方法
第二步:创建线程对象并启动线程,通过start()方法来间接调用run()方法,不能直接调用run()方法。
(2)自定义的类实现Runnable接口实现
第一步:定义run()方法
第二步:创建线程对象并启动线程。
如下:
4、线程的生命周期
创建:使用new运算符实例化一个线程对象,那么该线程对象就创建了。通过调用start()方法,可以启动该线程并且进入了就绪阶段。
就绪:就绪阶段可以分为两种情况:可运行状态(Runnable),正在运行状态(Running)。在任意一个时间片,只能有一个线程控制CPU。控制CPU的线程称为正在运行的线程,其他的线程称为可运行状态。
阻塞:处于阻塞状态的线程就失去了争抢CPU控制权的资格。阻塞状态又分为4种情况:休眠、等待、中断、挂起。
就绪休眠:sleep(n),经过n ms后该线程自动返回到就绪状态。
就绪挂起:suspend(),反过来使用resume()恢复该线程到就绪状态。这两对方法不推荐使用。
就绪中断:interrupt()方法,反过来,使用interrupted()方法。
就绪等待:wait()方法,反过来,使用notify()/notifyAll().
死亡:一个线程一旦运行完毕,即进行死亡状态,释放自身占用的资源。从死亡状态无法再返回到其他状态。
interrupt():中断一个线程。无论线程处于中断状态与否,isAlive()方法总是返回true.
interrupted():判断线程是否处于中断状态,如是中断状态返回true,并且将终止中断状态,返回到就绪状态。
isInterrupted():判断线程是否处于中断状态,如是中断状态返回true,否则false。并且当前线程的中断状态不会被清除。
5、线程的优先级
线程的优先级分为10个等级:1-10,1最低,10最高。Java的Thread类同时提供了3个常量表示优先级:MIN_PRIORITY (1), NORM_PRIORITY(5),MAX_PRIORITY(10),推荐为线程设置优先级时使用常量不要用数字。
线程的默认优先级是5
1、线程的概念
Thread,是一个进程更加微观的一个对象。进程是OS任务调度的最基本单位。
独立性:线程不能独立存在,线程依赖于进程存在。
存储区域:进程中的数据存在堆栈中,线程的数据存在于寄存器中。
粒度:线程小,进程大。
2、Java中关于线程的API
线程的API包括一个java.lang.Thread类和一个接口java.lang.Runnable接口。
Runnable接口只有一个抽象run()方法。而Thread类实际上是对Runnable接口的实现。
Thread的方法大概分为3类:
获取线程信息方法:getName()/getPriority()
设置线程信息方法:
setName()/setPriority()
有关线程生命周期的方法
Sleep()/join()/interrupt()/interrupted()/isAlive()/run()/resume()/suspend()/start()
3、实现线程的方式
Thread():构造一个缺省线程类
Thread(String name):构造一个名称为name的线程类
Thread(Runnable r):构造由R实现的线程类
Thread(Runnable r,String name):构造由R实现,名称为name的线程。
我们定义线程类,核心机制重写run()方法,在run()方法中写线程的功能代码。
(1)自定义的类继承Thread类实现
第一步:定义run()方法
第二步:创建线程对象并启动线程,通过start()方法来间接调用run()方法,不能直接调用run()方法。
(2)自定义的类实现Runnable接口实现
第一步:定义run()方法
第二步:创建线程对象并启动线程。
如下:
package com.tai.GX; public class ThreadText { public static void main(String[] args) { //第一种实现方式 创建匿名Thread的子类,复写Thread的run方法 运行的时候就会自动调用run方法 new Thread(){ public void run() { while (true) { try { Thread.sleep(1500); System.out.println(this.getName());//这里的this 就是当前正在运行的线程 相当于 Thread.currentThread system.out.println("this Thread can do something footloose!"); } catch (InterruptedException e) { e.printStackTrace(); } } }; }.start(); //第二种实现方式 创建Thread是传入一个Runnable接口的子类并复写其Run方法 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1500); System.out.println(Thread.currentThread().getName()); system.out.println("this Thread can do something footloose!"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); //因为Thread也实现了Runnable接口这里也可以这样用,我就是试试 其实不合理的 new Thread(new Thread(){ @Override public void run() { while (true) { try { Thread.sleep(1500); System.out.println(this.getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); //这里的既复写Thread的run方法 又传入了Runnable子类 这时候会发生什么情况呢 ? //这时候就需要看源码了:Thread类中有个Runnable对象,也就是构造方法传入的对象 Thread类的run方法会先判断时候有传入Runnable对象 //有的话就执行Runnable类的run方法 但是,这里复写了Thread的run方法,所以执行的时候就会执行子类复写过的run方法,所以这里就打印出 //From Runnable subClass! //From this thread! //super.run就是先调用负类的方法 如果去掉就不会打印出Runnable子类方法中的输出语句 new Thread(new Runnable() { @Override public void run() { System.out.println("From Runnable subClass!"); } }){ public void run() { super.run(); System.out.println("From this thread!"); }; }.start(); } }
4、线程的生命周期
创建:使用new运算符实例化一个线程对象,那么该线程对象就创建了。通过调用start()方法,可以启动该线程并且进入了就绪阶段。
就绪:就绪阶段可以分为两种情况:可运行状态(Runnable),正在运行状态(Running)。在任意一个时间片,只能有一个线程控制CPU。控制CPU的线程称为正在运行的线程,其他的线程称为可运行状态。
阻塞:处于阻塞状态的线程就失去了争抢CPU控制权的资格。阻塞状态又分为4种情况:休眠、等待、中断、挂起。
就绪休眠:sleep(n),经过n ms后该线程自动返回到就绪状态。
就绪挂起:suspend(),反过来使用resume()恢复该线程到就绪状态。这两对方法不推荐使用。
就绪中断:interrupt()方法,反过来,使用interrupted()方法。
就绪等待:wait()方法,反过来,使用notify()/notifyAll().
死亡:一个线程一旦运行完毕,即进行死亡状态,释放自身占用的资源。从死亡状态无法再返回到其他状态。
public class SuspendThread extends Thread { //定义构造方法 public SuspendThread(String name) { super(name); } //线程 体 public void run() { System.out.println("线程体开始执行"); for(int i=0;i<1000000;i++) { double d = 10; d = Double.MAX_VALUE/i+1; } for(int j=1;j<11;j++) { System.out.println(Thread.currentThread().getName() + "循环了" + j +"次"); if(j==5) { sleepThread(Thread.currentThread(),5000); } } System.out.println("线程体执行完毕"); //死亡状态 } public static void sleepThread(Thread t,long time) { if(t.isAlive()) try { System.out.println("线程开始休眠"); t.sleep(time); System.out.println("线程已醒,返回到就绪状态"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 挂起一个线程t * @param t */ @SuppressWarnings("deprecation") public static void suspendThread(Thread t) { //判断线程是否处于活动状态 ,指的就是就绪状态 if(t.isAlive()) { t.suspend(); System.out.println("线程已挂起"); } } /** * 恢复被挂起的线程 * @param t */ public static void resumeThread(Thread t) { if(!t.isInterrupted()) { t.resume(); System.out.println("线程已恢复!"); } } public static void main(String args[]) { SuspendThread st = new SuspendThread("A#");//创建状态 st.start();//就绪状态 //suspendThread(st);//阻塞状态 --挂起 //resumeThread(st);//将挂起的线程恢复,线程又重新进入了就绪状态 } }
几个复杂的方法: isAlive():是否处于活动状态,活动状态指的是从启动到死亡之间的时刻。 yield():一个正在运行的线程调用该方法后,失去CPU的控制权,重新和其他处于就绪状态的线程争抢CPU的控制权。
public class YieldThread extends Thread{ public YieldThread(String name) { super(name); } public void run() { for(int j=1;j<11;j++) { System.out.println(Thread.currentThread().getName() + "循环了" + j +"次"); if(j==3) { //让当前正在运行的线程放弃CPU的控制权 Thread.currentThread().yield(); } } } public static void main(String[] args) { for(int i=1;i<6;i++) { new YieldThread(i+"#").start(); } } }
join():让其他处于就绪状态的线程等待当前正在执行的线程。A正在执行B.join(long t)方法,B线程加入,其他线程待B执行完毕或者执行t毫秒后再执行。
public class JoinTest extends Thread{ /** * @param args */ public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); JoinTest t1 = new JoinTest("T1"); JoinTest t3 = new JoinTest("T3"); JoinTest t2 = new JoinTest("T2"); t3.start(); t1.start(); t2.start(); try { t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public JoinTest(String name) { super(name); } public void run() { System.out.println(this.getName() + "线程开始执行,当前时间:" + System.currentTimeMillis()); for(int i=1;i<6;i++) { System.out.println(this.getName() + "循环体循环了" + i + "次"); } System.out.println(this.getName() + "线程执行结束,当前时间:" + System.currentTimeMillis()); } }
interrupt():中断一个线程。无论线程处于中断状态与否,isAlive()方法总是返回true.
interrupted():判断线程是否处于中断状态,如是中断状态返回true,并且将终止中断状态,返回到就绪状态。
isInterrupted():判断线程是否处于中断状态,如是中断状态返回true,否则false。并且当前线程的中断状态不会被清除。
public class SuspendThread extends Thread { //定义构造方法 public SuspendThread(String name) { super(name); } //线程 体 public void run() { System.out.println("线程体开始执行"); for(int i=0;i<1000000;i++) { double d = 10; d = Double.MAX_VALUE/i+1; } for(int j=1;j<11;j++) { System.out.println(Thread.currentThread().getName() + "循环了" + j +"次"); if(j==5) { //sleepThread(Thread.currentThread(),5000); } } System.out.println("线程体执行完毕"); //死亡状态 } public static void sleepThread(Thread t,long time) { if(t.isAlive()) try { System.out.println("线程开始休眠"); t.sleep(time); System.out.println("线程已醒,返回到就绪状态"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 挂起一个线程t * @param t * @throws InterruptedException */ @SuppressWarnings("deprecation") public static void suspendThread(Thread t) { //判断线程是否处于活动状态 ,指的就是创建状态到死亡之间时段 if(t.isAlive()) { t.interrupt(); System.out.println("是否处于活动状态?" + t.isAlive()); System.out.println("线程已挂起"); } } /** * 恢复被挂起的线程 * @param t */ public static void resumeThread(Thread t) { if(t.isInterrupted()) //true { t.interrupted(); //清除中断 System.out.println("线程已恢复!"); } } public static void main(String args[]) { SuspendThread st = new SuspendThread("A#");//创建状态 st.start();//就绪状态 suspendThread(st);//阻塞状态 --挂起 resumeThread(st);//将挂起的线程恢复,线程又重新进入了就绪状态 } }
5、线程的优先级
线程的优先级分为10个等级:1-10,1最低,10最高。Java的Thread类同时提供了3个常量表示优先级:MIN_PRIORITY (1), NORM_PRIORITY(5),MAX_PRIORITY(10),推荐为线程设置优先级时使用常量不要用数字。
线程的默认优先级是5
相关文章推荐
- 黑马程序员---java线程Timer学习与总结
- java线程学习总结
- 黑马程序员java学习笔记之四(java多线程总结)
- 黑马程序员_Java学习日记4_面向对象总结3
- java多线程学习总结之四:线程的同步
- 黑马程序员_Java学习日记第四天-线程、Java1.5的新特性
- 黑马程序员-Java IO的学习总结
- 黑马程序员_java基础知识学习总结四
- 黑马程序员_Java学习日记5_面向对象总结4
- 黑马程序员——java学习数组的总结
- 黑马程序员_Java学习日记2_面向对象总结1
- 黑马程序员——java语言基础——总结一下学习过的类
- Java线程学习和总结
- 黑马程序员-Java网络编程学习总结
- Java线程学习和总结
- 黑马程序员_java基础知识学习总结一
- 黑马程序员————java线程的学习
- java多线程学习总结之二:线程状态的转换
- 黑马程序员———java视频一到四天的基础视频学习总结