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);
- }
- }