多线程编程(一)——多线程入门

俗话说好记性不如lai笔头,子曰:温故而知新~ 言归正传,本系列将从以下方面复习Java多线程编程相关的知识

  • 多线程入门
  • 线程安全
  • 多线程之间的通讯
  • 并发编程
  • 线程池

一、多线程入门

  1. 线程与进程的区别
  2. 为什么使用多线程
  3. 如何创建线程
  4. 线程的几种状态
  5. 守护线程与非守护线程
  6. 线程常用API

1.线程与进程的区别

进程:个人理解进程是指正在运行的一个应用程序;定义为:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的独立单位。

线程:是进程的一个实体,是CPU调度和分派的基本单位,比进程更小的能独立运行的基本单位;或者说线程是进程的一条执行路径。

区别:

a. 根本区别:进程是资源分配的基本单位,线程是程序执行的基本单位。

b. 主要差别:它们是操作系统不同的资源管理方式。系统会为每个进程分配不同的内存空间,进程间切换会有比较大的开销;同一进程内的线程共享进程的内存资源,除了CPU外,系统不会给线程分配内存,每个线程有自己独立的运行栈和程序计数器,线程间切换开销小。

2.为什么使用多线程

使多 CPU系统更加高效,提高工作效率。例如多线程上传或下载资源。

3.如何创建线程

a.继承Thread类,重写run方法。

创建CreateThread类:

public class CreateThread extends Thread {

public void run() {
	for (inti = 0; i< 10; i++) {
		System.out.println("i:" + i);
		}
	}
}

开启线程方式:

public static void main(String[] args) {

	CreateThread createThread = new CreateThread();
	createThread.start();
	
}

b.实现Runnable接口,重写run方法(推荐)

创建CreateRunnable类:

public class CreateRunnable implements Runnable {

@Override
public void run() {
	for (inti = 0; i< 10; i++) {
		System.out.println("i:" + i);
		}
	}

}

开启线程:

public static void main(String[] args) {
	CreateRunnable createThread = new CreateRunnable();
	Thread createThread = new Thread(createThread);
	createThread.start();
	
}

c.使用匿名内部类

Thread thread = new Thread(new Runnable() {
		public void run() {
			for (int i = 0; i< 10; i++) {
				System.out.println("i:" + i);
			}
		}
	});
thread.start();

为什么推荐第二种,因为Java的单一继承,多实现原则。第三种不方便管理,容易造成资源浪费。
注意:别忘调用Thread类的start()方法开启线程

4.线程的几种状态

图片来源于网络
多线程生命周期
大体上来说线程从创建到结束有5种状态。分别是新建状态(new)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)、死亡状态(Dead)
a.新建状态:当用new操作符创建一个线程实例时,此时Thread的run方法还未执行
b.就绪状态:通过thread实例调用start()方法即是启动了线程,创建线程运行的系统资源,并调度运行run()方法,当start方法返回后,线程就处于就绪状态
处于就绪状态的线程不一定立即运行run方法,还必须同其他线程竞争CPU时间,只有获得CPU执行时间才可以运行线程。
c.运行状态:当线程获得CPU时间后,进入运行状态,真正开始执行run()方法
d.阻塞状态:线程运行中有多种情况会导致阻塞

  1. 通过调用sleep方法进入睡眠状态或join()或发出了I/O请求时,线程会进入到阻塞状态,当sleep状态超时,join等待线程终止或者超时、或IO处理完毕时,线程重新转入就绪状态。
  2. 等待阻塞:运行中的线程执行wait()方法,使本线程进入到等待阻塞状态
  3. 同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态

e:死亡状态:线程执行完了或因异常退出了run()方法,该线程结束生命周期。
为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false.

5.守护线程与非守护线程

Java中有两种线程:一种是用户线程,另一种是守护线程。
用户线程:用户自定义的线程,主线程停止,用户线程不会停止
守护线程:当进程不存在或主线程停止,守护线程被停止
使用setDaemon(true)方法设置为守护线程。

6.线程常用API

a.setPriority():设置线程的优先级,范围为1-10,其中10最高,默认值为5
b.join():线程a,b;在b中调用a.join()会等a执行完成才开始执行b线程,目的是将两个交替执行的线程合并为顺序执行。
c.yield():Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果)
yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。
结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。
欢迎关注个人公众号,技术干货分享:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路漫-其修远兮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值