一、串行与并发
1. 串行: 指程序中的程序段必须按照先后顺序来执行 极大地浪费了CPU资源
2. 并行: 指系统中的多个程序或程序段能够同时执行,这里的同时执行并不是指某一个时刻多段程序在同进执行(除非有多个CPU),而是CPU能把时间分给不同的程序段。
二、进程与线程
联系:1. 进程包括线程
2. 一个进程中可以有多个线程,并且一个进程中至少有一个线程
3. 当进程中没有了线程,这个进程就会被迫停止
区别: 进程之间资源不共享,线程之间资源共享
三、线程的生命周期
1.线程的生命周期:
一个线程被实例化完成到这个线程被销毁的过程称为线程的生命周期。
2.线程的状态:
1)新生态(New) :
一个线程对象被实例化完成,但是没有做任何操作。当用new操作符创建一个线程时,未start之前。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码。
2)就绪态(Runnable) :
一个线程已经被开启,已经开始争抢cpu时间。当start()方法返回后,线程就处于就绪状态。
3)运行态 (Running):
一个线程抢到了CPU时间,开始执行这个线程的逻辑。真正开始执行run()方法.
4)阻塞态 (Blocked):一个线程在运行的过程中,受到某些操作的影响,放弃了已经获取到的CPU时间片,并且不再参与CPU时间片的争抢,此时线程处于挂起状态。
5)死亡态(Dead):一个线程对象需要被销毁
四、线程的开辟方式
1.自定义线程子类(继承方式)
可读性强
但不可再继承其他类
public class ThreadCreate {
public static void main(String []args)
{
//线程实例化
//1.继承Thread类,做一个线程子类(自定义的线程子类)
MyThread mt=new MyThread();
/*注意:需要调用start方法,使线程启动
start方法会开启一个新的线程,来执行run中的逻辑
如果直接调用run方法,则线程mt不会进入就绪态
*/
mt.start();
System.out.println("主线程中的逻辑执行结束咧");
}
}
/*
这是一个自定义的线程类
*/
class MyThread extends Thread{
/*
需要重写run方法
将需要并发执行的任务写到run方法中
*/
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println("子线程中的逻辑:"+i);
}
}
}
运行结果:
2.实现Runnable接口`(实现方式)
用的多
//2.通过Runnable接口
Runnable r =new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++) {
System.out.println("子线程2中的逻辑:"+i);
}
}
};
Thread mt2=new Thread(r);
mt2.start();
运行结果:
五、线程的常用方法
1.线程的命名:
1)实例化一个线程对象
Thread t=new Thread();
t.setName(“custom”);
2)实例化一个线程对象的同时,通过构造 方法对线程进行命令
Thread(Runnable r,String name)
Thread t=new Thread(()->{},“custom”);
3)使用自定义的线程类,在实例化线程对象的同时,进行名称的赋值,需要给线程类添加对应的构造方法
public class ThreadMethod {
public static void main(String []args){
//线程的命名
/*
1.实例化一个线程对象
Thread t=new Thread();
t.setName("custom");
*/
/*
2.实例化一个线程对象的同时,通过构造方法对线程进行命令
Thread(Runnable r,String name)
Thread t=new Thread(()->{},"custom");
*/
/*
3.使用自定义的线程类,在实例化线程对象的同时,进行名称的赋值
需要给线程类添加对应的构造方法
*/
MyThread2 t=new MyThread2("custom");
System.out.println(t.getName());
}
}
class MyThread2 extends Thread{
public MyThread2(){}
public MyThread2(String name){
this.setName(name);
}
}
2.线程的休眠
线程休眠可使一个线程由运行状态切换到阻塞态,当休眠时间到了以后由阻塞状态回到就绪状态,抢到资源可到运行状态
public class ThreadMethod {
public static void main(String []args){
threadSleep();
}
private static void threadSleep(){
//1.实例化一个线程对象
MyThread2 t=new MyThread2();
t.start();
}
}
class MyThread2 extends Thread{
public MyThread2(){}
public MyThread2(String name){
this.setName(name);
}
@Override
public void run(){
for(int i=0;i<5;i++){
System.out.println(i);
//线程休眠
//1.参数:毫秒为单位的时间差 表示休眠时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
3.线程的设置优先级
设置线程的优先级 只是修改这个线程可以抢到CPU时间片的概率,并不是优先级高的线程一定能抢到CPU时间片。
public class ThreadMethod {
public static void main(String []args){
threadPriority();
}
/*
设置线程的优先级
*/
private static void threadPriority(){
/*
设置线程的优先级 只是修改这个线程可以抢到CPU时间片的概率
并不是优先级高的线程一定能抢到CPU时间片
优先级的设置,是一个整数【0,10】的整数,默认是 5
*/
Runnable r=new Runnable() {
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
};
Thread t1=new Thread(r,"Thread-1");
Thread t2=new Thread(r,"Thread-2");
//设置优先级 必须放到线程开始start方法前
t1.setPriority(10);
t2.setPriority(1);
t1.start();
t2.start();
}
}
class MyThread2 extends Thread{
public MyThread2(){}
public MyThread2(String name){
this.setName(name);
}
@Override
public void run(){
for(int i=0;i<5;i++){
System.out.println(i);
//线程休眠
//1.参数:毫秒为单位的时间差 表示休眠时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4.线程的礼让
指的是将当前的运行状态的线程去释放自己的CPU资源,由运行状态再回到就绪状态
package com.wayy.thread;
public class ThreadMethod {
public static void main(String []args){
threadYield();
}
/*
线程的礼让
*/
private static void threadYield(){
//线程礼让,指的是将当前的运行状态的线程去释放自己的CPU资源
//由运行状态再回到就绪状态
Runnable r = new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
if(i==3){
Thread.yield();
}
}
}
};
Thread t1=new Thread(r,"Thread-1");
Thread t2=new Thread(r,"Thread-2");
t1.start();
t2.start();
}
}
class MyThread2 extends Thread{
public MyThread2(){}
public MyThread2(String name){
this.setName(name);
}
@Override
public void run(){
for(int i=0;i<5;i++){
System.out.println(i);
//线程休眠
//1.参数:毫秒为单位的时间差 表示休眠时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果: