一 Java 多线程编程
1) 什么是程序:
指令 + 数据的byte序列,如: qq.ext
2) 什么是进程:
正在运行的程序, 是程序动态的执行过程(运行于主存储器)
3) 什么是线程:
在进程内部, 并发运行的过程(方法)
4) 什么是并发:
进程是并发运行的, OS将时间划分为很多时间片段,尽可能均匀分配并给正在运行的程序,微观上进程走走停停, 宏观上都在运行这
种都运行的现象叫:并发,但是不是绝对意义上的"同时"。
二 Java 如何 创建一个线程
1) 使用Thread 类 : 线程包含一个可以运行的过程(方法)
Thread 类中包含方法 run()
2) 创建一个具体线程,需要继承于Thread类
3) 覆盖run()方法(就是更新运行过程),实现用户自己的过程
4) 创建线程是实例的一个线程
5) 线程运行过程
New
interrupt() ↓ start() IO完成
Runnable ← ←
超时 获取cpu ↓ ↑出让yield() ↑IO Wait
Wait Block ← Running → IO Block ↑
Sleep Block ← readLine()
sleep() ↓ run()结束
Dead
6) 使用线程实例的start() 方法启动线程,启动以后线程会尽快的去并发执行run()
Thread t = new Thread(){
public void run(){
}
};
或者一个类继承Thread
class Foo extends Thread{
public void run(){
}
}
例子
1 public class InitThreadDemo {
2 public static void main(String[] args) {
3 //方法1
4 Thread t1 = new Thread(){
5 public void run(){
6 }
7 };
8 t1.start();
9 //方法2
10 Thread t2 = new Thread(new Runnable(){
11 public void run(){
12 Thread t = Thread.currentThread();
13 System.out.println(t.getId()+","+t.getName());
14 System.out.println("hi");
15 }
16 });
17 t2.start();
18 //方法3
19 Thread t3 = new Thread(){
20 public void run() {
21 System.out.println("Hi ,t3");
22 }
23 };
24 t3.start();
25 //方法4
26 new Thread(){
27 public void run() {};
28 }.start();
29 //方法5
30 Koo k = new Koo();
31 k.start();
32 }
33 }
34 //方法5的一部分
35 class Koo extends Thread{
36 public void run() {
37 }
38 }
三 线程的常用属性
1)线程的优先级(资源紧张的时候,尽可能优先)
t3.setPriority(Thread.Max_PRIORITY);有10优先级,
优先级高的线程获得执行的机会多,机会的多少
不能通过代码干预
默认的优先级是5
2)后台线程(守护线程,精灵线程)
t1.setDeamon(true); //Deamon: 守护神,守护精灵,魂魄
Java进程的 结束: 当前所有前台线程都结束时,Java 进程结束后台线程,
不管是否结束,都被停掉!因为并发的现象,后台线程不会立即结束!
3) 线程名字,线程编号是线程对象的属性
getName() getId()
4) 当前线程
Thread main = Thread.currentThread();
例子
1 public class ThreadDemo {
2 public static void main(String[] args) {
3 Person1 p1 = new Person1();
4
5 Person2 p2 = new Person2();
6
7 Person3 p3 = new Person3();
8 p1.setDaemon(true);//将p1设置为后台线程
9 p1.setPriority(Thread.MIN_PRIORITY);//设置为最低优先级0
10 p3.setPriority(Thread.MAX_PRIORITY);//设置为最高优先级10
11 p1.start();//尽快启动线程的run()方法,执行线程过程
12 p2.start();
13 p3.start();
14 }
15
16 }
17 class Person1 extends Thread{
18 public void run() {//覆盖父类Thread的run()方法,提供具体的过程
19 for(int i=0;i<100;i++){
20 System.out.println("做弹弓子打你家玻璃!");
21 Thread.yield();//出让,回到runnable状态
22 }
23 System.out.println("弹弓over");
24 }
25 }
26 class Person2 extends Thread{
27 public void run() {//覆盖父类Thread的run()方法,提供具体的过程
28 for(int i=0;i<100;i++){
29 System.out.println("你是谁呀!");
30 Thread.yield();//出让,回到runnable状态
31 }
32 System.out.println("你是谁呀over");
33 }
34 }
35 class Person3 extends Thread{
36 public void run() {//覆盖父类Thread的run()方法,提供具体的过程
37 for(int i=0;i<100;i++){
38 System.out.println("查水表的!");
39 Thread.yield();//出让,回到runnable状态
40 }
41 System.out.println("查水表的over");
42 }
43 }
四.Sleep状态的打断唤醒
1) Thread.sleep(times)
使当前线程从 Running 状态放弃处理器,进入Block状态,休眠times(单位为毫秒),休眠
结束后,再返回到Runnale 状态
例子
1 public class SleepDemo {
2 public static void main(String[] args) {
3 System.out.println("Start");
4 try {
5 Thread.sleep(5000);//线程休息5000毫秒(5秒)
6 } catch (InterruptedException e) {
7 // TODO Auto-generated catch block
8 e.printStackTrace();
9 }
10 System.out.println("End");
11 }
12 }
2) interrupt()方法打断/中断
使用该方法可以让一个线程提前唤醒另外一个sleep Block的线程
3)被唤醒线程会出现中断异常
例子
1 public class SleepDemo{
2 public static void main(String[] args) {
3 final Thread main = Thread.currentThread();
4 Thread t = new Thread(){
5 @Override
6 public void run() {
7 System.out.println("启动线程1");
8 System.out.println("准备开始打断main线程");
9 try{
10 Thread.sleep(500);
11 }catch(InterruptedException e){
12 e.printStackTrace();
13 }
14 main.interrupt();
15 }
16 };
17 t.start();
18
19 try{
20 System.out.println("Start");
21 Thread.sleep(1000);
22 System.out.println("end");
23 }catch(InterruptedException e){
24 e.printStackTrace();
25 System.out.println("吵醒!");
26 }
27 }
28 }
29 运行结果:
30 Start
31 启动线程1
32 准备开始打断main线程
33 java.lang.InterruptedException: sleep interrupted
34 at java.lang.Thread.sleep(Native Method)
35 at com.tarena.day20.SleepDemo2.main(SleepDemo2.java:23)
36 吵醒!
五 线程阻塞现象 Block
1) IO Block是由IO操作时出发的,和Sleep Block 不同,Sleep Bolck是由sleep()方法出发的
2) IO Bloeck 的触发方法如: readLine().,nextLine(),next(),nextInt()等
3) 一般IO读取方法都会发生IO Block
例子:
1 import java.util.Scanner;
2
3 public class IOBlockDemo {
4 public static void main(String[] args) {
5 Thread t = new Thread(){
6 public void run() {
7 Scanner in = new Scanner(System.in);
8 System.out.println("输入信息");
9 //nextLint() 使当前线程的状态有Running迁移到
10 //IO Block, 当IO完成时候(输入了字符串) IO Block结束
11 //返回到Runnable,然后再继续执行
12 String str = in.nextLine();
13 System.out.println(str);
14 }
15 };
16 t.start();
17
18 }
19
20 }