java线程

本文深入探讨Java线程的概念、创建(包括继承Thread、实现Runnable和Callable接口)、线程同步(同步代码块、同步方法及死锁)以及线程通信的相关API。重点介绍了线程同步的实现方式和使用步骤。
摘要由CSDN通过智能技术生成

线程

1.线程的相关概念
2.线程的创建和启动 ★
3.线程的停止
4.线程的常见方法(Thread)
5.线程的生命周期 ★
6.线程的同步
7.线程的通信

线程的相关概念

概念

程序:为了让计算机完成某个特定的功能,编写的一系列有序指令的集合,是一段静止的代码段

进程:正在运行的程序,它有自己的生命周期

线程:轻量级的进程。一个进程可以划分为若干个执行单位,每个执行单位可以看做是一个线程,一个进程可以包含多个线程

单线程:一个进程中,在同一个时刻,只能运行一个线程,必须等待该线程执行结束,其他线程才能开始执行

多线程:一个进程中,在同一个时刻,可以同时运行多个线程

	单核cpu: 仅仅只是貌似 “同时”
	多核cpu: 有可能出现真正“同时”
	比如:qq 同时打开多个线程,打开qq新闻、打开qq聊天窗口

多线程的好处

1、有效的占用了cpu的空闲时间,从一定程度上提高了效率
2、提高了用户的体验性
3、将一个复杂的进程拆分成若干个小的线程,提高代码的分离性和维护性

线程的创建和启动

方式一:继承Thread

定义线程类:

class MyThread extends Thread{
	public void run(){
		//编写新线程要执行的任务体
	}
}

创建新线程,并启动
new MyThread().start();

方式二:实现Runnable

定义任务类:

class MyRunnable implements Runnable{
	public void run(){
		//编写新线程的任务体
	}
}

创建新线程,并启动
new Thread(new MyRunnable()).start();

方式三:实现Callable接口

Callable 接口类似于 Runnable,但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而 Callable 依赖 FutureTask 类获取返回结果。

class MyThread implements Callable<String>{
   public String call() throws Exception{
      //编写任务体
   }
}

创建并启动

FutureTask futureTask = new FutureTask(new MyThread());
new Thread(futureTask).start();
Integer i= futureTask.get();

实现Runnable接口和继承Thread的区别:★

1、方式二避免了单继承的局限性,使用更加灵活
2、方式二更适合处理多线程共享资源的情况

实现Callable接口和实现Runnable接口的区别:

1、实现Callable接口的方式,方法有返回值;实现Runnable接口的方式,方法没有返回值
2、实现Callable接口的方式,call方法可以抛出异常;实现Runnable接口的方式,run方法不会抛出异常

线程的停止

1.stop 已经过时
2.Interrupt 只能中断睡眠、等待这些状态,会抛出InterruptedException异常,并没有真正的结束线程
3.采用通知的方法 ★
  	步骤1:让需要停止的线程中添加一个循环标记,默认值为true
  	步骤2:让需要停止的线程中添加一个公共的set方法,用于更新循环标记
 	步骤3:需要停止该线程时,调用set方法即可

线程的常见方法

currentThread 获取当前线程对象     //Thread.currentThread().getName();
setName设置线程名称
getName获取线程名称
setPriority设置线程优先级1——10
getPriority获取线程优先级
sleep休眠
interrupt中断休眠状态
yield线程的礼让
join线程的插队
setDaemon设置守护线程

线程的生命周期

线程状态转换
新建:创建了线程对象,但没有调用start方法
就绪:调用了start方法,但没有抢占到cpu占用权
运行:抢占到了cpu占用权
死亡:线程正常执行结束|error或Exception意外退出|break或return正常退出
堵塞:在运行状态期间调用了 sleep|wait|join。当sleep时间到或调用了notify等,也会从堵塞状态切换到就绪状态

线程的同步

  • 线程的同步如何发生的?
    当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误

  • 如何避免线程的同步问题?
    对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,不让其他线程参与执行

线程的同步的实现方式 ★

对象+synchronized 搭配使用

方式一:同步代码块

synchronized(锁对象){
	//需要上锁的代码(同步的代码)
}

方式二:同步方法

public synchronized 返回类型 方法名(参数列表){
	//需要上锁的代码(同步的代码)
}
  • 注意:
    普通的同步方法,锁对象是:this
    静态的同步方法,锁对象是:当前类.class

  • 同步要求:
    多个线程使用的锁对象必须是同一个!!!

线程的同步前提

1、多线程
2、有共享资源
3、线程的任务体中有对共享资源处理语句

使用同步的步骤 ★

1、先分析需要上锁的代码
2、分析需要同步代码块还是同步方法
3、检测多线程使用的锁对象是否为同一个!!!

线程的死锁

发生原因:多个线程都需要用到多把锁,每一个线程都需要对方线程的锁对象,如果多个线程互不相让,导致死锁问题

释放锁和不释放锁的操作

一)释放锁

1、线程正常执行结束
2、遇到return或break
3、error或Exception
4、调用了wait

二)不会释放锁

1、sleep
2、yield
3、suspend

线程的通信

线程的通信也就是 线程之间的 “交流”,也就是通过一定的方法,实现线程的控制!

相关的API ★

一、wait
语法:

锁对象.wait();

特点:

1、让当前线程等待,直到其他线程调用了该锁对象的notify或notifyAll方法为止,否则将一直等待
2、wait的调用 必须在同步的前提下
3、wait的调用 会导致锁的释放
4、如果等待结束也就是被唤醒后,则继续从断点处往下执行!

二、notify和notifyAll

语法:

锁对象.notify()|notifyAll();

特点:

1、notify:唤醒当前锁对象下等待的单个线程。优先级较高的优先唤醒,如果优先级一样,则随机;notifyall:唤醒当前锁对象下所有等待的线程
2、notify和notifyAll的调用,必须在同步的前提下

注意:

wait、notify、notifyAll和当前同步代码的锁对象都必须是同一个!否则报异常!!!!

线程通信步骤

1、需要先将代码实现同步
2、根据需要,调用wait或notify 、notifyAll  ★
3、检测wait、notify、notifyAll的调用者和同步的锁对象是否是同一个
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值