【Java多线程编程核心技术】1.Java多线程技能-笔记总结
2017-11-13 09:10
996 查看
相关链接:
【Java多线程编程核心技术】1.Java多线程技能-笔记总结
【Java多线程编程核心技术】2.对象及变量的并发访问(上)-笔记总结
【Java多线程编程核心技术】2.对象及变量的并发访问(下)-笔记总结
【Java多线程编程核心技术】3.线程间通信 -笔记总结
【Java多线程编程核心技术】4.Lock的使用-笔记总结
【Java多线程编程核心技术】5.定时器Timer-笔记总结
【Java多线程编程核心技术】6.单例模式与多线程-笔记总结
【Java多线程编程核心技术】7.拾遗增补-笔记总结
按【Ctrl+Shift+Esc】 弹出,点击进程选项,这里面的东西就是一个个进程。
进程是受操作系统管理的基本运行单元(原文)
线程则可以理解成为进程中独立运行的子任务,例如在QQ.exe运行时,就有很多子任务在同时允许。如:好友视频线程、下载文件线程、传输数据线程等。
多线程的优势:可以充分的利用计算机cpu的资源。相较于单任务环境,多线程可以来回在多个线程任务间进行切换,避免了在单任务环境下某个任务等待自己所期待的事件而不
4000
能运行时长时间的占用cpu.
通过继承Thread类或实现Runnable接口:
1.代码的运行结果与代码执行顺序或调用顺序是无关的
2.如果多次调用start()方法,则会出现异常Exception in thread “main” java.lang.IllegalThreadStateException
3.调用start()方法,通知“线程规划器”此线程已经准备就绪,等待调用线程对应的run()方法,如果直接在main()方法里调用run()方法,那就是main线程去执行run方法里的代码,需等run方法执行完以后才能去执行后面的代码,不具备异步执行的效果。
4.执行start()方法的顺序不代码线程启动的顺序
5.Thread类也实现了Runnable接口
Thread构造函数:
public Thread(Runnable target) 这里不光可以传入一个Runnable接口的对象,还可以传入一个Thread类的对象,也就是完全可以将一个Thread对象中的run方法交由其他的线程进行调用!!!
synchronized关键字:实现同步效果,可以在任意对象及方法上加锁,加锁的这段代码称为“互斥区”或“临界区”。
非线程安全:多个线程对同一个对象的同一个实例进行操作时会出现值被更改、值不同步的情况,进而影响程序执行流程。
print()方法在内部是同步的:
新创建的线程的默认名字为:Thread-X,X代表数字,如Thread-0,Thread-1,Thread-2
isAlive:测试线程是否处于活动状态,就是线程已经启动且尚未终止。
sleep():在制定的毫秒数内让当前“正在执行的线程”休眠(暂停执行) //Thread.sleep(2000)
getId(): 取得线程的唯一标识。
yield():放弃当前的cpu资源,将它让给其他的任务去占用CPU执行时间,但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。
interrupted():测试当前线程是否已经中断,执行后具有将状态标志清除为false的功能 //public static boolean interrupted()
isInterrupted():测试线程是否已经中断,但不清除状态标志 //public boolean isInterrupted()
异常法-停止线程
在沉睡中停止(sleep()+interrupt()):
在sleep状态下停止某一线程,会进入catch语句,并清除停止状态值,使之变成false。
同样,先interrupted(),再sleep(),也是同样的效果
暴力停止线程-stop()
当调用stop()时会抛出java.lang.ThreadDeath异常
stop()已经作废,1.可能让一些清理性的工作得不到完成 2.会锁定的对象进行了“解锁”,导致得不到同步处理,导致数据不一致。
用return停止线程(interrupt()+return):
建议使用“抛异常”的方法来实现停止线程,因为在catch块中还可以将异常向上抛,使线程停止的事件得以传播
resume():恢复线程
缺点:
1.独占:极易造成公共的同步对象的独占,使其他线程无法访问公共同步对象(尤其注意当与println()方法搭配使用时)
2.不同步
优先级分为1~10,默认值为5 (NORM_PRIORITY=5)
线程优先级的继承特性:例如A线程启动B线程,则B线程的优先级与A是一样的
优先级具有规则性:CPU尽量将执行资源让给优先级比较高的线程
优先级具有随机性:不要把优先级与运行结果的顺序作为衡量的标准,优先级较高的线程并不一定每一次都先执行完run()方法中的任务,线程的优先级与调用run()方法顺序无关
优先级越高,相对越快
Daemon的作用:为其他线程的运行提供便利服务
【Java多线程编程核心技术】1.Java多线程技能-笔记总结
【Java多线程编程核心技术】2.对象及变量的并发访问(上)-笔记总结
【Java多线程编程核心技术】2.对象及变量的并发访问(下)-笔记总结
【Java多线程编程核心技术】3.线程间通信 -笔记总结
【Java多线程编程核心技术】4.Lock的使用-笔记总结
【Java多线程编程核心技术】5.定时器Timer-笔记总结
【Java多线程编程核心技术】6.单例模式与多线程-笔记总结
【Java多线程编程核心技术】7.拾遗增补-笔记总结
进程与多线程的概率及线程优点
按【Ctrl+Shift+Esc】 弹出,点击进程选项,这里面的东西就是一个个进程。
进程是受操作系统管理的基本运行单元(原文)
线程则可以理解成为进程中独立运行的子任务,例如在QQ.exe运行时,就有很多子任务在同时允许。如:好友视频线程、下载文件线程、传输数据线程等。
多线程的优势:可以充分的利用计算机cpu的资源。相较于单任务环境,多线程可以来回在多个线程任务间进行切换,避免了在单任务环境下某个任务等待自己所期待的事件而不
4000
能运行时长时间的占用cpu.
使用多线程
一个进程正在运行时至少也有一个进程正在运行,例如学习Java时的用到的第一个方法-main()方法,也是通过一个叫作main的线程执行的public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); } 输出:main //这里的main和main方法没有任何关系,仅仅只是同名而已
通过继承Thread类或实现Runnable接口:
public class MyThread extends Thread { @Override public void run() { super.run(); System.out.println("extends Thread"); } } public static void main(String[] args) { MyThread mythread = new MyThread(); mythread.start(); System.out.println("运行结束!"); } public class MyRunnable implements Runnable { @Override public void run() { System.out.println("implements Runnable!"); } } public static void main(String[] args) { Runnable runnable=new MyRunnable(); Thread thread=new Thread(runnable); thread.start(); System.out.println("运行结束!"); } 输出: 运行结束! extends Thread! 或 implements Runnable!
1.代码的运行结果与代码执行顺序或调用顺序是无关的
2.如果多次调用start()方法,则会出现异常Exception in thread “main” java.lang.IllegalThreadStateException
3.调用start()方法,通知“线程规划器”此线程已经准备就绪,等待调用线程对应的run()方法,如果直接在main()方法里调用run()方法,那就是main线程去执行run方法里的代码,需等run方法执行完以后才能去执行后面的代码,不具备异步执行的效果。
4.执行start()方法的顺序不代码线程启动的顺序
5.Thread类也实现了Runnable接口
Thread构造函数:
public Thread( ); public Thread(Runnable target); public Thread(String name); public Thread(Runnable target, String name); public Thread(ThreadGroup group, Runnable target); public Thread(ThreadGroup group, String name); public Thread(ThreadGroup group, Runnable target, String name); public Thread(ThreadGroup group, Runnable target, String name, long stackSize);
public Thread(Runnable target) 这里不光可以传入一个Runnable接口的对象,还可以传入一个Thread类的对象,也就是完全可以将一个Thread对象中的run方法交由其他的线程进行调用!!!
synchronized关键字:实现同步效果,可以在任意对象及方法上加锁,加锁的这段代码称为“互斥区”或“临界区”。
非线程安全:多个线程对同一个对象的同一个实例进行操作时会出现值被更改、值不同步的情况,进而影响程序执行流程。
print()方法在内部是同步的:
public void println(String x){ synchronized(this){ print(x); newLine(); } }
常用API介绍
currentThread():返回代码段正在被哪个线程调用的信息 //Thread.currentThread().getName()新创建的线程的默认名字为:Thread-X,X代表数字,如Thread-0,Thread-1,Thread-2
isAlive:测试线程是否处于活动状态,就是线程已经启动且尚未终止。
package mythread; public class CountOperate extends Thread { public CountOperate() { System.out.println("CountOperate---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("CountOperate---end"); } @Override public void run() { System.out.println("run---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("run---end"); } } public class Run { public static void main(String[] args) { CountOperate c = new CountOperate(); Thread t1 = new Thread(c); System.out.println("main begin t1 isAlive=" + t1.isAlive()); t1.setName("A"); t1.start(); System.out.println("main end t1 isAlive=" + t1.isAlive()); } } 输出结果: CountOperate---begin Thread.currentThread().getName()=main Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=false CountOperate---end main begin t1 isAlive=false main end t1 isAlive=true run---begin Thread.currentThread().getName()=A Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=false run---end
sleep():在制定的毫秒数内让当前“正在执行的线程”休眠(暂停执行) //Thread.sleep(2000)
getId(): 取得线程的唯一标识。
yield():放弃当前的cpu资源,将它让给其他的任务去占用CPU执行时间,但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。
停止线程
interrupt():在当前线程中打了一个停止的标记,并不是真正的停止线程interrupted():测试当前线程是否已经中断,执行后具有将状态标志清除为false的功能 //public static boolean interrupted()
isInterrupted():测试线程是否已经中断,但不清除状态标志 //public boolean isInterrupted()
异常法-停止线程
public class MyThread extends Thread { @Override public void run() { super.run(); try { for (int i = 0; i < 500000; i++) { if (this.interrupted()) { System.out.println("已经是停止状态了!我要退出了!"); throw new InterruptedException(); } System.out.println("i=" + (i + 1)); } System.out.println("我在for下面"); } catch (InterruptedException e) { System.out.println("进MyThread.java类run方法中的catch了!"); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } } i=146942 i=146943 i=146944 i=146945 i=146946 i=146947 i=146948 end! 已经是停止状态了!我要退出了! 进MyThread.java类run方法中的catch了! java.lang.InterruptedException at sort.MyThread.run(MyThread.java:12)
在沉睡中停止(sleep()+interrupt()):
public class MyThread extends Thread { @Override public void run() { super.run(); try { System.out.println("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止!进入catch!当前线程状态:"+this.isInterrupted()); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(200); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } } run begin end! 在沉睡中被停止!进入catch!当前线程状态:false java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at sort.MyThread.run(MyThread.java:9)
在sleep状态下停止某一线程,会进入catch语句,并清除停止状态值,使之变成false。
同样,先interrupted(),再sleep(),也是同样的效果
暴力停止线程-stop()
当调用stop()时会抛出java.lang.ThreadDeath异常
stop()已经作废,1.可能让一些清理性的工作得不到完成 2.会锁定的对象进行了“解锁”,导致得不到同步处理,导致数据不一致。
用return停止线程(interrupt()+return):
public class MyThread extends Thread { @Override public void run() { while (true) { if (this.isInterrupted()) { System.out.println("停止了!"); return; } System.out.println("timer=" + System.currentTimeMillis()); } } }
建议使用“抛异常”的方法来实现停止线程,因为在catch块中还可以将异常向上抛,使线程停止的事件得以传播
暂停线程
suspend():暂停线程resume():恢复线程
缺点:
1.独占:极易造成公共的同步对象的独占,使其他线程无法访问公共同步对象(尤其注意当与println()方法搭配使用时)
2.不同步
线程的优先级
设置方法-setPriority()优先级分为1~10,默认值为5 (NORM_PRIORITY=5)
线程优先级的继承特性:例如A线程启动B线程,则B线程的优先级与A是一样的
优先级具有规则性:CPU尽量将执行资源让给优先级比较高的线程
优先级具有随机性:不要把优先级与运行结果的顺序作为衡量的标准,优先级较高的线程并不一定每一次都先执行完run()方法中的任务,线程的优先级与调用run()方法顺序无关
优先级越高,相对越快
守护线程
守护线程:Java中有两种线程,用户线程与守护线程(典型的应用就是垃圾回收器),当进程中不存在非守护线程了,则守护线程自动销毁//这里介绍gc比较少,后面在总结《深入理解Java虚拟机》时会更详细的介绍Daemon的作用:为其他线程的运行提供便利服务
Mythread thread=new Mythread(); thread.setDaemon(true); //设置为守护线程
相关文章推荐
- 《Java 多线程编程核心技术》学习笔记及总结
- 【Java多线程编程核心技术】2.对象及变量的并发访问(下)-笔记总结
- 【Java多线程编程核心技术】5.定时器Timer-笔记总结
- 【Java多线程编程核心技术】4.Lock的使用-笔记总结
- 【Java多线程编程核心技术】7.拾遗增补-笔记总结
- Java多线程编程核心技术---Java多线程技能
- java多线程编程核心技术第一章笔记
- 《Java多线程编程核心技术》--第1章--Java多线程技能
- 二、java多线程编程核心技术之(笔记)——如何停止线程?
- Java多线程编程核心技术(第五章定时器Timer笔记)
- java多线程编程核心技术笔记-停止线程interrupt()方法
- Java多线程编程核心技术 第一章笔记
- Java多线程编程核心技术 阅读笔记
- java多线程编程核心技术笔记-脏读
- 看书笔记--JAVA多线程编程核心技术
- 一、java多线程编程核心技术之(笔记)——多线程的实现
- 多线程编程核心技术读书笔记(一):Java多线程技能
- java多线程核心技术编程笔记
- java多线程编程核心技术知识点总结
- Java多线程编程核心技术---Java多线程技能