线程
1、概述:
-
进程:
操作系统中一个程序及其数据在处理机上顺序执行时所发生的活动(是一个程序)
-
线程:
也是轻量级进程,是进程中某个单一顺序的控制流,一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。
-
多进程
在操作系统中同时运行多个任务(程序)
-
多线程
在同一应用程序中有多个顺序流同时执行
-
线程的生命周期
1.新建状态:创建出线程对象,线程处于新建状态
2.就绪状态:线程调用start方法,当前线程会处于就绪状态,处于就绪状态的线程拥有争夺CPU资源的使用权力
3.运行状态:如果当前线程争夺到CPU使用权,那该线程进入run方法,进入run方法的线程处于运行状态
4.阻塞状态:处于运行状态的线程,如果发生了睡眠或者是控制台打印等需要发生等待的操作,该线程就处于阻塞状态,处于阻塞状态的线程会释放CPU的使用权
5.死亡状态:run方法执行结束,当前线程任务完成,该线程处于死亡状态
2、创建线程
-
注意:
在Java中的多线程包含:主线程、普通线程、守护线程 主线程:指的就是main函数,直接由jvm调用 普通线程:自定义的线程就是普通线程 守护线程:守护线程可以自定义,但是在Java中有默认的守护线程,例如:垃圾回收线程
实现Runnable接口
package com.itguo.thread;
/**
* 实现线程的方式
* 实现Runnable接口
* 这种方式也是我们常使用的方式,因为我们以后会面向接口开发
*/
public class ThreadTest02 {
public static void main(String[] args) {
//这是一个可以运行的对象,而不是线程对象
MyThread01 myThread01 = new MyThread01();
//创建线程对象 ,通过构造将myThread01传进去
Thread thread = new Thread(myThread01);
//设置线路名称
thread.setName("t1");
//启动线程
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread01 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
继承Thread类
package com.itguo.thread;
/**
* 实现线程的方式:
* 继承Thread
* ThreadImpl extends Tread{
* run(){
*
* }
* }
*/
public class ThreadTest01 {
public static void main(String[] args) {
//创建线程对象
ThreadImpl thread = new ThreadImpl();
//启动线程
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("主线程"+i);
}
}
}
class ThreadImpl extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("自定义线程"+i);
}
}
}
- 输出结果:
主线程0
自定义线程0
自定义线程1
主线程1
主线程2
主线程3
自定义线程2
自定义线程3
自定义线程4
自定义线程5
自定义线程6
自定义线程7
自定义线程8
自定义线程9
主线程4
主线程5
主线程6
主线程7
主线程8
主线程9
- 注意:主线程和自定义线程是并发执行的状态,同时去争夺CPU资源的使用权
线程常用方法简单使用:
package com.itguo.thread;
/**
* 实现线程的第一种方式:
* 继承Thread
* ThreadImpl extends Tread{
* run(){
*
* }
* }
* 在Java中的多线程包含:主线程、普通线程、守护线程
* 主线程:指的就是main函数,直接由jvm调用
* 普通线程:自定义的线程就是普通线程
* 守护线程:守护线程可以自定义,但是在Java中有默认的守护线程,例如:垃圾回收线程
*
* @author ShuaiGUO
*/
public class ThreadTest01 {
public static void main(String[] args) {
//创建线程对象
ThreadImpl thread1 = new ThreadImpl();
ThreadImpl thread2= new ThreadImpl();
ThreadImpl thread3 = new ThreadImpl();
//设置线程名称
thread1.setName("t1");
thread2.setName("t2");
thread3.setName("t3");
//启动线程
thread1.start();
thread2.start();
thread3.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
try {
//模拟睡眠
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadImpl extends Thread{
@Override
public void run() {
//获取当前线程对象Thread.currentThread()
Thread thread = Thread.currentThread();
//获取线程名称thread.getName()
//System.out.println(Thread.getName());
for (int i = 0; i < 10; i++) {
System.out.println(thread.getName()+" "+i);
try {
//模拟睡眠
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 输出结果:
main 0
main 1
main 2
main 3
main 4
main 5
main 6
main 7
main 8
main 9
t1 0
t2 0
t3 0
t1 1
t2 1
t3 1
t1 2
t2 2
t3 2
t3 3
t2 3
t1 3
t2 4
t3 4
t1 4
t3 5
t2 5
t1 5
t3 6
t2 6
t1 6
t1 7
t2 7
t3 7
t3 8
t1 8
t2 8
t2 9
t3 9
t1 9
- join() 合并线程的方法;isAlive()方法线程是否处于存活状态;suspend()挂起线程;强制杀死线程stop();唤醒线程resume();唤醒正在睡眠的线程,利用了异常机制interrupt();
package com.itguo.thread;
//join 合并线程的方法,指定线程进入长期阻塞状态,直到剩余线程进入死亡状态,该线程才执行!!!
public class ThreadTest08 {
public static void main(String[] args) {
//创建线程对象
Thread t1 = new Thread(new CreateThread03());
//Thread t2 = new Thread(new CreateThread03());
//线程名称
t1.setName("t1");
//t2.setName("t2");
//开启线程
t1.start();
//t2.start();
System.out.println("t1线程是否处于存活状态 "+t1.isAlive());
for (int i = 0; i <= 10; i++) {
/* if (i == 5){
try {
//合并线程
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/
System.out.println(Thread.currentThread().getName()+ " "+ i);
//模拟睡眠
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//唤醒正在睡眠的t1线程,利用了异常机制
t1.interrupt();
//唤醒t1线程
//t1.resume();
}
}
class CreateThread03 implements Runnable {
@Override
public void run() {
//模拟睡眠一小时
try {
Thread.sleep(1000 * 60 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i <= 10; i++) {
/* if (i == 5){
//线程自己把自己挂起(处于阻塞状态)
Thread.currentThread().suspend();
}*/
/* if (i == 7){
//强制杀死线程
Thread.currentThread().stop();
}*/
System.out.println(Thread.currentThread().getName()+ " "+ i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程的生命周期java代码解释
package com.itguo.thread;
/**
* 线程的生命周期
* 1.新建状态:创建出线程对象,线程处于新建状态
* 2.就绪状态:线程调用start方法,当前线程会处于就绪状态,处于就绪状态的线程拥有争夺CPU资源的使用权力
* 3.运行状态:如果当前线程争夺到CPU使用权,那该线程进入run方法,进入run方法的线程处于运行状态
* 4.阻塞状态:处于运行状态的线程,如果发生了睡眠或者是控制台打印等需要发生等待的操作,该线程就处于阻塞状态,处于阻塞状态的线程会释放CPU的使用权
* 5.死亡状态:run方法执行结束,当前线程任务完成,该线程处于死亡状态
*/
public class ThreadTest03 {
public static void main(String[] args) {
//这是一个可以运行的对象,而不是线程对象
MyThread02 myThread02 = new MyThread02();
//创建线程对象 ,当前线程处于新建状态
Thread thread = new Thread(myThread02);
//设置线路名称
thread.setName("t1");
//启动线程,线程处于就绪状态,处于就绪状态的线程拥有争夺CPU资源的使用权力
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread02 implements Runnable{
@Override
public void run() {//进入run方法的线程处于运行状态
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
//当前线程睡眠会处于阻塞状态,处于阻塞状态的线程会释放CPU使用权
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//当run方法结束之后,线程处于死亡状态
}
匿名内部类创建线程对象
package com.itguo.thread;
public class ThreadTest04 {
public static void main(String[] args) {
//创建线程对象
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
//启动线程对象
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出结果
main 0
Thread-0 0
Thread-0 1
main 1
Thread-0 2
main 2
Thread-0 3
main 3
Thread-0 4
main 4
Thread-0 5
main 5
Thread-0 6
main 6
Thread-0 7
main 7
Thread-0 8
main 8
Thread-0 9
main 9
3、多线程在jvm上的分布
1.在java的多线程种,一个线程对应一个栈
2.栈中的资源是线程不共享的
3.堆和方法区中的资源是线程共享的
JVM:
栈:局部变量的声明
creatThread t1
creatThread t2
creatThread t3
堆:成员变量,和new出来的部分
new creatThread();
new creatThread();
new creatThread();
方法区:字节码,常量池
CreateThread.class
ThreadTest.class
4、线程调度模型
- 抢占式调度模型(java使用)
- 均分式调度模型