4.4.1 线程与进程
线程
定义:程序中单独顺序的控制流。
线程本身依靠进程进行运行,线程是程序中的顺序控制流,只能使用分配给进程的资源和环境。
进程
定义:执行中的程序。
一个进程可以包括一个或者多个线程。
一个进程至少包括一个线程。
单线程程序
进程中只有一个线程,main方法就是主线程。
多线程程序
在一个程序中运行多个任务。多线程的目的是更好的使用cpu资源。
4.4.2 线程的实现
在java中,线程的实现有2中方式:继承Thread类和实现Runnable接口。
一个Thread对象只能调用一次start方法,否则exception。
Thread类
java.lang.Thread
必须重写run方法
class MyThread extends Thread{ private String name; public MyThread(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(name + ":"+ i); } } }
public static void main(String[] args) { MyThread t1 = new MyThread("t1"); MyThread t2 = new MyThread("t2"); t1.start(); t2.start(); //如果这里调用run方法,不是启用线程,而是方法调用!!! }
Runnable接口
class MyThread2 implements Runnable{ private String name; public MyThread2(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(name + ":"+ i); } } }
public static void main(String[] args) { MyThread2 t1 = new MyThread2("t1"); MyThread2 t2 = new MyThread2("t2"); new Thread(t1).start(); new Thread(t2).start(); //如果这里调用run方法,不是启用线程,而是方法调用!!! }
4.4.3 线程的状态
- 创建状态:准备好了一个thread对象
- 就绪状态:调用了start方法,加入cpu的调度序列
- 运行状态:正在执行run方法
- 阻塞状态:暂时停止执行
- 终止状态:也叫死亡状态,线程销毁
4.4.4 线程的常用方法
- getName() : 取得线程名称
- Thread.currentThread(); 取得当前运行的线程对象
class MyThread2 implements Runnable{ private String name; public String getName() { return name; } public MyThread2(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(Thread.currentThread().getName()+ ":"+ i); } } }
public static void main(String[] args) { MyThread2 r1 = new MyThread2("t1"); MyThread2 r2 = new MyThread2("t2222222222222"); Thread t1 = new Thread(r1, r1.getName()); Thread t2 = new Thread(r2, r2.getName()); t1.start(); t2.start(); }
- isAlive(); 判断线程是否启动,start之前是false
- join(); 线程的强行运行,执行完之后才把cpu让给其他线程。
class MyThread2 implements Runnable{ private String name; public String getName() { return name; } public MyThread2(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(Thread.currentThread().getName()+ ":"+ i); } } }
public static void main(String[] args) { MyThread2 r1 = new MyThread2("t1"); Thread t = new Thread(r1); t.setName(r1.getName()); t.start(); for (int i = 0; i < 50; i++) { if(i > 10){ try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("in main thread : " + i); } }
输出结果in main thread : 0 in main thread : 1 in main thread : 2 in main thread : 3 t1:0 in main thread : 4 t1:1 in main thread : 5 t1:2 in main thread : 6 in main thread : 7 in main thread : 8 in main thread : 9 t1:3 in main thread : 10 t1:4 t1:5 t1:6 t1:7 t1:8 t1:9 一直到 t1:996 t1:997 t1:998 t1:999 in main thread : 11 in main thread : 12 in main thread : 13 in main thread : 14 。。。。。 in main thread : 45 in main thread : 46 in main thread : 47 in main thread : 48 in main thread : 49
- Thread.sleep(millis); 线程的休眠
- Thread.yield(); 从执行态到就绪态,等待调度。
4.4.5 线程的优先级
优先级顺序:
- MIN_PRIORITY : 1
- MAX_PRIORITY: 10
- NORMAL_PROORITY: 5 (default)
4.4.6 线程的同步 : 多个线程操纵共享数据的时候需要同步
同步代码块
synchronized (同步对象){ 需要同步的代码块; }
同步方法
synchronized void synchronizedMethod(){ xxxxx; }
买车票的问题
class SellTicket implements Runnable{ private int numTickets = 5; @Override public void run() { synchronized (this){ System.out.println(--numTickets); } } }
public static void main(String[] args) { SellTicket r = new SellTicket(); Thread window1 = new Thread(r); Thread window2 = new Thread(r); Thread window3 = new Thread(r); window1.start(); window2.start(); window3.start(); }
同步方法
class SellTicket implements Runnable{ private int numTickets = 5; @Override public void run() { decrementTicket(); } public synchronized void decrementTicket(){ System.out.println(--numTickets); } }