Java中的线程--对线程来个多方位理解!

本文深入探讨Java中的线程,包括线程生命周期的五个阶段、三种创建线程的方式、ABA问题和CAS原理、volatile与synchronized关键字以及Lock的使用,最后通过示例解析线程的原子性、可见性和有序性以及死锁问题。
摘要由CSDN通过智能技术生成

Java中的线程总结

一、线程的生命周期

1. 进程与线程的定义

(1) 定义:可以简单的理解进程与线程。可以把进程看成一项具体的任务,而线程是为了完成该任务来分解的子任务。
(2) 比如小明今天下5点要去理发店剪头发,这是一项任务(进程),理发店的人可能比较多,因此理发的环节有洗、剪、吹。这每一个环节就是子任务(线程)。
(3) 多线程可以提高效率。

在这里插入图片描述

2. 进程与线程的特征

(1)线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位。
(2)一个进程由一个或多个线程组成,线程是一个进程中的代码不同执行路线。
(3)进程之间相互独立,同一进程下的多个线程共享程序的内存空间以及资源。
(4)线程也被认为是轻量级的进程。

3. 线程的生命周期

线程的生命周期一共有5个阶段:创建、就绪、运行、阻塞、自然死亡。
(1)创建有3种方式(二中有解释)
(2)就绪:start();此时并没有执行,就绪不一定CPU(抢占式)会执行
(3)运行:run()和call()
(4)阻塞(block)(4种):

  1. sleep()
    自己休眠一定时间,释放资源,让其他资源去抢占。当休眠时间过后,变为就绪状态,重新去抢占CPU资源。

  2. yield()
    自己释放资源后,立马变成就绪状态去抢夺资源。

  3. join()
    直到调用join方法的线程执行完毕才能访问资源。

  4. wait()
    只能在synchronized语句中使用。当一个线程执行到wait方法时,它就进入到一个和该对象相关的等待池,同时释放对象的机锁,使得其他线程能够访问,可以通过notify,notifyAll方法来唤醒等待的线程

(5)自然死亡状态(不包括意外死亡)
在这里插入图片描述

二、创建线程的3种方式

1.继承Thread类

继承Thread类来创建线程,然后重写Thread类里面的run()方法。

package simeng.thread;

public class ThreadDemo01 {
   
    //此处的main也是一个线程哦,叫做主线程!
	public static void main(String[] args) {
   
		Thread t1=new MyThread();
		Thread t2=new MyThread();
		Thread t3=new MyThread();
		t1.start();
		t2.start();
		t3.start();
		
	}
	/**
	 * 自定义的线程类,完成1到10的打印
	 * @author Ssimeng
	 *
	 */
	public static class MyThread extends Thread{
   
		@Override
		public void run() {
   
			for(int i=0;i<10;i++) {
   
				System.out.println(Thread.currentThread().getName()+": "+i);
				try {
   
					Thread.sleep(200);
				} catch (InterruptedException e) {
   
					e.printStackTrace();
				}
			}
		}
	}

}

结论:线程是抢占式的,处在runnable状态下的线程,谁抢到资源谁就可以执行,因此顺序是无法确定的。
执行结果:
在这里插入图片描述

2.实现Runnable接口

2.实现Runnable接口来创建线程,然后重写run()方法。

package simeng.thread;

public class ThreadDemo02 {
   
	public static void main(String[] args) {
   
		Thread t1=new Thread(new MyThread2());
		Thread t2=new Thread(new MyThread2());
		Thread t3=new Thread(new MyThread2());
		t1.start();
		t2.start();
		t3.start();
	}
	/**
	 * 采用实现Runnable接口的方式自定义线程
	 * 功能依旧是打印1到10,与继承Thread类的效果一样
	 * @author SSimeng
	 *
	 */
	public static class MyThread2 implements Runnable{
   
		@Override
		public void run() {
   
			for(int i=0;i<10;i++) {
   
				System.out.println(Thread.currentThread().getName()+": "+i);
				try {
   
					Thread.sleep(200);
				} catch (InterruptedException e) {
   
					e.printStackTrace();
				}
			}
		}
	}

}

3.实现Callable接口

3.实现Callable接口来创建线程,然后重写call()方法。

package simeng.newthread;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class ThreadDemo03 {
   
	
	public static void main(String[] args) throws Exception {
   
		//FutureTask实现了Runnable接口
		Thread t1=new Thread(new FutureTask<Integer>(new Mythread03())
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值