Java多线程总结(一)

一.进程与线程

进程是程序动态执行的一次过程,它经历了代码加载,执行到执行完毕的一个完整过程,这个过程也是进程本身产生,发展到消亡的过程。多进程操作系统能同时运行多个进程,由于CPU具有分时机制,所以每个进程都能循环获得自己的CPU时间片。由于CPU执行速度非常快,使得所有进程好像是同时运行一样。
线程是比进程更小的执行单位,线程是在进程的基础之上的进一步划分。多线程是指一个进程在执行过程中可以产生多个线程,这些线程可以同时存在,同时运行,一个进程可以包含多个同时执行的线程。区别如下图:
图一

二.Java中线程的实现

1.继承Thread类

Thread类是在java.lang包中定义的,只要继承了Thread类,此类就称为多线程类。在此类中必须要明确的覆写Thread类中run()方法,此方法称为线程的主体,定义格式如下:
图二
调用Thread类中的start()方法可以启动线程。线程的运行需要本地操作系统的支持,start()方法的部分定义如下图:
图三
可知声明使用了native关键字,这个关键字表示调用本机的操作系统底层函数。如果一个类通过继承Thread类实现,那么只能调用一次start()方法,如果重复调用会报"IllegalThreadStateException"异常。代码实例如下:

class MyThread extends Thread{
	private String name;
	public MyThread(String name){
		this.name = name;
	}
	public void run(){
		for(int i = 0;i < 10;i++){
			System.out.println(name+"运行i,="+i);
		}
	}
}
public class ThreadDemo {
	public static void main(String[] args) {
		MyThread m1 = new MyThread("线程A");
		MyThread m2 = new MyThread("线程B");
        m1.start();
        m2.start();
	}
}

线程B运行i,=0
线程A运行i,=0
线程B运行i,=1
线程A运行i,=1
线程B运行i,=2
线程A运行i,=2
线程B运行i,=3
线程A运行i,=3
线程B运行i,=4
线程A运行i,=4
线程B运行i,=5
线程A运行i,=5
线程B运行i,=6
线程A运行i,=6
线程B运行i,=7
线程A运行i,=7
线程B运行i,=8
线程A运行i,=8
线程A运行i,=9
线程B运行i,=9

结果不唯一

2.实现Runnable接口

Runnable接口中只定义了一个抽象方法:public void run();通过接口实现多线程的方法如下:
图四
实际上实现接口还是要通过调用start()方法启动线程的。Thread类中有二个构造方法用来接收Runnable接口的子类实例对象,以此启动线程。

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target, String name) {
    init(null, target, name, 0);
}

无论哪种方式,都需要Thread类来启动线程。

class MyThread implements Runnable{
	private String name;
	public MyThread(String name){
		this.name = name;
	}
	public void run(){
		for(int i = 0;i < 10;i++){
			System.out.println(name+"运行i,="+i);
		}
	}
}
public class ThreadDemo {
	public static void main(String[] args) {
		MyThread m1 = new MyThread("线程A");
		MyThread m2 = new MyThread("线程B");
		Thread r1 = new Thread(m1);
		Thread r2 = new Thread(m2);
        r1.start();
        r2.start();
	}
}
线程A运行i,=0
线程B运行i,=0
线程B运行i,=1
线程B运行i,=2
线程B运行i,=3
线程B运行i,=4
线程B运行i,=5
线程B运行i,=6
线程B运行i,=7
线程B运行i,=8
线程B运行i,=9
线程A运行i,=1
线程A运行i,=2
线程A运行i,=3
线程A运行i,=4
线程A运行i,=5
线程A运行i,=6
线程A运行i,=7
线程A运行i,=8
线程A运行i,=9

3.区别和联系

实现Runnable接口比继承Thread类有以下优势:

  • 1.适合多个相同程序代码的线程去处理同一资源的情况
  • 2.可以避免单继承带来的局限
  • 3.增强了程序的健壮性,代码能够被多个程序共享,代码与数据是独立的。

三.线程的状态

任何线程都有创建,就绪,运行,阻塞,死亡五种状态。线程转换如下所示:
图五
1.创建状态
在程序中用构造方法创建一个线程对象时,新的线程对象便处于新建状态,此时它已经有了自己的内存空间和其它资源,但它还是处于不可运行的状态。如:Thread thread = new Thread();
2.就绪状态
调用新建线程的start()方法就可以启动线程,启动时线程就进入了就绪状态,它将进入就绪队列排队,等待CPU服务。
3.运行状态
当就绪状态的线程被调用并获得处理器资源时,线程进入了运行状态,它会自动调用run()方法,方法中定义了该线程的操作和功能。
4.阻塞状态
一个正在执行的线程在一些特殊情况下,比如被人为挂起或较耗时的输入输出时,将让出CPU并中止自己的执行进入堵塞状态,此时它不能进入就绪状态,只有当阻塞状态的原因消除时才能重新进入就绪状态。在可执行状态下,调用sleep(),wait(),suspend()等方法可进入阻塞状态。
5.死亡状态
线程调用stop()方法或者run()方法执行完毕后,即处于死亡状态,此时线程不再具有运行的能力。

四.线程的操作方法

线程的操作方法主要在Thread类中,如下图所示:
图六
图七
图七为线程优先级,优先级越高越有可能先执行,但哪个线程先执行是由CPU调度决定的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值