Java多线程(一)

一、认识多线程

进程 VS 线程

进程:打开任务管理器,里面有多个进程。
在这里插入图片描述

进程是系统进行资源分配和调度的独立单位。每一个进程都有它自己的内存空间和系统资源

  • 独立性:拥有自己独立的资源,每个进程拥有自己的私有地址空间。
  • 动态性:程序是一个静态的指令集合,而进程加入了时间的概念。
  • 并发性:多个进程可以在单个处理器并发执行。

线程:线程是进程的一部分。每个进程可以执行多个任务,这个任务就是线程。(可以想象成某个程序的子模块)

分类:

  1. 用户级线程:管理过程全部由用户程序完成,操作系统内核心只对进程进行管理。

  2. 系统级线程(核心级线程):由操作系统内核进行管理。操作系统内核给应用程序提供相应的系统调用和应用程序接口API,以使用户程序可以创建、执行以及撤消线程。

why 多线程?

  • 线程之间可以共享内存
  • 创建代价小(不需要重新分配系统资源)

二、使用多线程

常用的有两种方法:

  • 继承 Thread 类,重写**run()**方法
  • 实现 Runnable 接口

示例1:

public class MyThread extends Thread{
	private int num = 10;
	
	public void run() {
		while(true) {
			System.out.println(Thread.currentThread().getName()+"-->"+num);
			num--;
			if(num==0) {
				return;
			}
		}
	}
	
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		Thread a = new Thread(myThread,"thread1");
		a.start();
	}
}
  • 重写 run() 方法,使用 start() 启动线程
  • Thread.currentThread().getName() 用于获取线程名,即Thread a = new Thread(myThread,"thread1");的构造方法的第二个参数。

示例2:


public class MyThread1 implements Runnable{
	private int num = 10;
	
	public void run() {
		while(true) {
			System.out.println(Thread.currentThread().getName()+"-->"+num);
			num--;
			if(num==0) {
				return;
			}
		}
	}
	
	public static void main(String[] args) {
		MyThread myThread1 = new MyThread();
		Thread a = new Thread(myThread1,"thread1");
		a.start();
	}
}

  1. run() VS start()
  • run():仅仅是封装被线程执行的代码,直接调用是普通方法

  • start():首先启动了线程,然后再由jvm去调用该线程的run()方法。

  1. main方法也是一个线程
public class MyThread1 {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
    }
}

/***
main
***/

三、线程的优先级

  1. 线程的优先级可以在某种程度上影响执行线程的顺序,但设置优先级仅仅只是个建议,优先级高不一定先执行,这取决与操作系统
  2. 设置优先级使用 setPriority() 方法,参数的取值范围为 1 <= x <= 10,不在范围内则抛出IllegalArgumentException 异常
  3. Thread.MIN_PRIORITY(1)   Thread.MAX_PRIORITY(10)   Thread.NORM_PRIORITY(5)是Thread类里面的变量,线程创建时优先级默认为5.
  4. 线程设置优先级要在调用start方法之前
public class MyThread1 {
    public static void main(String[] args) {
    	Thread thread = new Thread(()->{
    		for(int i = 0;i < 6;i++) {
    			System.out.println("lamada.."+i);
    		}
    	});
    	System.out.println("thread的优先级是"+thread.getPriority());
    	thread.setPriority(10);
    	System.out.println("thread的优先级是"+thread.getPriority());
    	thread.start();
    	for(int i = 0;i < 6;i++) {
			System.out.println("main.."+i);
		}
    	
    }
}

在这里插入图片描述

  • Runnable接口时函数式接口,可以用Lamada表达式建立Runnable对象。

四、线程的生命周期

线程的生命周期有 5 种状态:

  • 新建( New
  • 就绪 ( Runnable )
  • 运行 ( Running )
  • 阻塞 ( Blocked )
  • 死亡 ( Dead )
    在这里插入图片描述

五、操作线程的方法

1.join() 线程插队

public class MyThread1 {
    public static void main(String[] args) throws InterruptedException {
    	Thread thread = new Thread(()->{
    		for(int i = 0;i < 20;i++) {
    			System.out.println("lamada.."+i);
    		}
    	});
    	thread.start();
    	
    	for(int i = 0;i < 20;i++) {
    		if(i==10) {
    			thread.join();
    		}
			System.out.println("main.."+i);
		}
    	
    }
}

运行结果:

main..0
main..1
main..2
main..3
main..4
main..5
main..6
main..7
main..8
main..9
lamada..0
lamada..1
lamada..2
lamada..3
lamada..4
lamada..5
lamada..6
lamada..7
lamada..8
lamada..9
lamada..10
lamada..11
lamada..12
lamada..13
lamada..14
lamada..15
lamada..16
lamada..17
lamada..18
lamada..19
main..10
main..11
main..12
main..13
main..14
main..15
main..16
main..17
main..18
main..19

  • 很显然,当main()方法中的 i 为 10时,main()方法被插队了,只有thread执行完成后,main()才执行。

2.slepp() 线程睡眠 抱着资源睡觉

处于sleep()中的线程不会执行,调用后线程进入阻塞状态。

Thread.sleep(long millis);//参数为毫秒数,1000ms = 1s

3.yield() 线程让步

  • sleep()暂停主线程后会给其他线程机会,而yield()只会给优先级相同或更高的线程执行机会
  • yield()不会阻塞进程,只是将该线程进入就绪状态。
  • yield()不会抛出异常,而sleep()会

4.改变线程优先级

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值