Java 线程与并发研究系列四(多线程)

当使用多个线程来同时运行多个任务时,有时候需要对某项共享资源进行操作,怎样使得一个任务不会干涉另外一个任务呢?这时候就需要

使用锁来使得资源的访问变得互斥,也就是同时只能有一个任务对共享资源进程访问。

Java中能够通过Object的wait()和notify()方法来安全的访问共享资源。Java SE5的并发库还提供了await()和signal()方法的Condition对象来实

现资源的安全访问。

下面我们来了解一下一些常用的线程同步相关方法

notify()和notifyAll()的不同,notify():在众多等待同一个锁的任务中,只有一个被唤醒,所以如果使用notify()时,就必须保证被唤醒的是恰当

的任务。notify一般用于具有唤醒同步块的对象。notifyAll()是唤醒所有正在等待同一个锁的任务。

wait()方法的作用是将调用该方法的线程挂起,和sleep(),yield()这些方法不同的是,在调用wait方法后,该对象上的锁会被释放掉,也就是

在此声明:我已经做完所有能做的事,因此我在这里等待,但是我希望其他的synchronized操作在条件适合的情况下能够执行。

wait,notify,notifyAll,这些方法的是基类Object的一部分,而不是属于Thread的一部分,我们可能会感到奇怪,为什么针对线程的功能却

作为基类的一部分来实现,这是因为这些操作的锁也是所有对象的一部分,所以你可以在任何的同步控制方法或者同步控制块中调用wait()

notify(),notifyAll(),如果在非同步控制方法中调用这些方法时,程序能够编译通过,但运行时会抛出IllegalMonitorStateException异常,也

就是在调用这些方法的任务在调用这些方法前必须拥有对象锁。

下面我们通过一个例子来熟悉这些方法的使用。

现在有一个场景是:一辆车,需要多次进行涂蜡和抛光,在涂蜡之前必须进行抛光,在抛光之前必须进行涂蜡,刚开始肯定是从涂蜡开始

然后进行抛光,然后再涂蜡,以此循环。下面给出这个场景的代码:

public class MyTest{
	
	public static volatile boolean isStop = false;
	public static void main(String[] args) throws InterruptedException{
		Car car = new Car();
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.submit(new Wax(car));
		exec.submit(new Buff(car));
		TimeUnit.SECONDS.sleep(5);
		isStop = true;
		exec.shutdownNow();
	}
	
}

class Car{
	private boolean waxOn= false;//涂蜡的标志位,ture表示正在涂蜡
	
	/**
	 * 涂蜡*/
	public synchronized void wax(){
		waxOn = true;
		notifyAll();
	}
	
	/**
	 * 抛光*/
	public synchronized void buff(){
		waxOn = false;
		notifyAll();
	}
	
	/**
	 * 等待涂蜡*/
	public synchronized void waitForWax()throws InterruptedException{
		while(waxOn == false){
			wait();
		}
	}
	/**
	 * 等待抛光*/
	public synchronized void waitForBuff()throws InterruptedException{
		while(waxOn == true){
			wait();
		}
	}
}

class Wax implements Runnable{
	Car car;
	public Wax(Car car){
		this.car = car;
	}
	@Override
	public void run() {
		while(!MyTest.isStop){
			try {
				car.waitForBuff();
				
				TimeUnit.MILLISECONDS.sleep(200);//涂蜡所需时间
				System.out.println("正在涂蜡");
				car.wax();
			} catch (InterruptedException e) {
				System.out.println("涂蜡完毕");
			}		
		}
		System.out.println("结束涂蜡");
	}
}
class Buff implements Runnable{
	Car car;
	public Buff(Car car){
		this.car = car;
	}
	
	@Override
	public void run() {
		while(!MyTest.isStop){
			try {
				car.waitForWax();
				TimeUnit.MILLISECONDS.sleep(200);//抛光所需时间
				System.out.println("正在抛光");
				car.buff();
			} catch (InterruptedException e) {
				System.out.println("抛光完毕");
			}		
		}
		System.out.println("结束抛光");
	}	
}


上面的代码我们就实现了这个场景,最先开始提交涂蜡的任务,然后提交抛光的任务,确保任务是从涂蜡开始的。waxOn这个变量就是涂蜡

和抛光的标志为false时表示正在进行抛光,等待涂蜡,为true时表示正在进行涂蜡,等待抛光。涂蜡时,先调用waitForBuff()方法将抛光的线

程挂起,然后调用wax()方法进行涂蜡,在这个方法中将waxOn标志位设为true,涂蜡完毕后使用notifyAll()唤醒正在等待这辆车的抛光的任务。

在抛光时,先调用waitForWax()方法将涂蜡的线程挂起,然后调用buff()方法进行抛光,并将waxOn标志位设为false,抛光完毕后使用notifyAll()

方法唤醒正在等待这辆车的涂蜡任务。

让这个过程持续5秒,然后调用shutdownNow(),这个方法会调用由他控制的线程的interrupt()方法。至于为什么要使用一个while循环包围wait

方法,这是因为,可能由于其他原因,还有其他任务也在等待这辆车的同一个锁,而这个锁被唤醒时,可能会导致其他任务获取这个锁,从而

导致这个任务继续被挂起。

内容概要:本文档详细介绍了基于弹性架构搜索(Elastic Architecture Search, EAS)结合Transformer编码器进行多变量时间序列预测的项目实例。项目旨在自动化优化多变量时间序列预测模型结构,提升预测精度鲁棒性,降低计算资源消耗,实现模型轻量化。通过MATLAB实现,项目采用Transformer编码器的多头自注意力机制,结合EAS的弹性权重共享和分阶段搜索策略,解决了高维多变量时间序列的复杂依赖建模、架构搜索计算资源需求高、模型过拟合、多步预测误差积累、数据异构性缺失值处理、复杂模型训练收敛等挑战。最终,项目构建了一个高度模块化和可扩展的系统设计,适用于智能制造、能源管理、智慧交通等多个工业场景。 适合人群:具备一定编程基础,对时间序列预测、深度学习及MATLAB有一定了解的研发人员和研究人员。 使用场景及目标:①自动化优化多变量时间序列预测模型结构,提升预测精度鲁棒性;②降低计算资源消耗,实现模型轻量化;③实现高度模块化可扩展的系统设计,促进人工智能在工业领域的深度应用;④提供科研教学的典范案例工具,探索深度学习架构搜索在时序预测的前沿技术;⑤促进多变量时序数据融合异质信息处理能力,推动MATLAB深度学习工具箱的应用扩展。 其他说明:项目不仅聚焦于模型性能提升,更注重计算资源节约和应用落地的可行性。借助弹性架构搜索自动化调参,减少人工经验依赖,加快模型迭代速度,降低开发门槛。结合Transformer编码器的表达能力,显著改善多变量时间序列预测中的长期依赖捕捉和异质数据融合问题,为各类时间序列分析任务提供一种全新的解决方案。项目通过详细的代码实现和注释,帮助用户理解Transformer机制弹性架构搜索如何协同工作,实现多变量时间序列预测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值