12.3笔记

使用同步机制的这种方式解决线程安全问题,但是不知道具体的锁对象在哪里添加,并且锁对象在哪里释放锁对象,对于这种情况

 Jdk5以后Java提供了一个更具体的锁对象:Lock

 Lock实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作

 Lock是一个接口,所以它在使用的是ReentrantLock子实现类

         publicvoid lock()获取锁。

        public void unlock()试图释放此锁

public class SellTicketDemo {
	public static void main(String[] args) {
		//创建资源对象
		SellTicket st = new SellTicket() ;
		//创建线程对象
		Thread t1 = new Thread(st, "窗口1") ;
		Thread t2 = new Thread(st, "窗口2") ;
		Thread t3 = new Thread(st, "窗口3") ;
		//启动线程
		t1.start() ;
		t2.start() ;
		t3.start() ;
	}
}


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SellTicket implements Runnable {
	//定义一个100张票
	private int tickets = 100 ;
	//Jdk5以后Java提供了更具的锁定操作:加锁和释放锁
	//定义一个具体锁对象
	private  Lock lock = new ReentrantLock() ;//具体的lock锁
	public void run() {
		//模拟电影院一直有票
		while(true){
			try{
				//获取锁
				lock.lock() ;
				if(tickets>0){
					//加入延迟操作
					try {
						Thread.sleep(100) ;
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+正在出售第"+(tickets--)+"张票");
				}
			}finally{
				//试图释放锁对象
				lock.unlock() ;
			}
			
		}
	}

}

使用同步机制可以解决多线程的安全问题,但是自身也会有弊端:

1)同步---->执行效率低(每一个线程在抢占到CPU的执行权,会去将(门)关闭,别的线程进不来)

2)容易出现死锁现象

死锁线程:两个或者两个以上的线程出现了互相等待的情况,就会出现死锁!

线程通信的问题:使用消费者和生产者模式

public class DieLock extends Thread {
	//定义一个成员变量
	private boolean flag ;
	public DieLock(boolean flag){
		this.flag = flag ;
	}
	//重写run()方法
	public void run() {
		if(flag){
			synchronized(MyLock.objA){
				System.out.println("if objA");
				synchronized (MyLock.objB) {
				System.out.println("if objB");
				}
			}//代码执行完毕,objA锁相当于才能被释放掉
		}else {
			synchronized (MyLock.objB) {
				System.out.println("else objB");
				synchronized(MyLock.objA){
					System.out.println("else objA");
				}
			}
		}
		
	}
}

public class DieLockDemo {
	public static void main(String[] args) {
		//创建线程类对象
		DieLock dl1 = new DieLock(true) ;
		DieLock dl2 = new DieLock(false);
		//启动线程
		dl1.start() ;
		dl2.start() ;
	}
}
public class MyLock {
	//创建两把锁对象
	public static final Object objA = new Object() ;
	public static final Object objB = new Object() ;
}

提供:资源对象:Student类     提供一些成员变量:姓名 和年龄

生产者线程:SetThread类:  生产一些学生数据(设置学生数据)

消费者线程:GetThread类:  输出学生数据

测试类:StudentDemo类,实现多线程环境

使用刚才的这几个类:模拟生产消费者模式,生产者SetThread产生学生数据,而GetThread消费者线程输出学生数据,发现一个问题,

输出学生数据的时候,是null--0

 

 对于每一个线程都在创建自己的学生对象,两个线程操作的两个对象而不是同一个对象,所以应该解决:

 将学生对象成员变量,然后通过构造方法进行传递,在测试类中,创建学生对象(同一个资源对象)让多个线程对这个学生对象进行操作

 改进:为了数据多并且效果更明显,加入循环语句进行操作,给生产者线程和消费者线程分别加入循环语句(while循环)


public class StudentDemo {
	public static void main(String[] args) {
		//创建一个资源对象
		Student s = new Student() ;
		//创建资源对象
		SetThread st = new SetThread(s) ;
		GetThread gt = new GetThread(s) ;
		//创建线程类对象
		Thread t1 = new Thread(st) ;
		Thread t2 = new Thread(gt) ;
		//分别启动线程
		t1.start() ;
		t2.start() ;
	}
}

public class Student {
	String name;
	int age ;
}


//生产者线程
public class SetThread implements Runnable {
	private Student s ;
	public SetThread(Student s){
		this.s = s ;
	}
	public void run() {
		//设置数据
		s.name = "RNG" ;
		s.age = 666 ;
	}

}


//消费者线程
public class GetThread implements Runnable {
	private Student s ;
	public GetThread(Student s){
		this.s = s ;
	}
	public void run() {
		//输出语句
		System.out.println(s.name+"---"+s.age);
	}
}

改进:为了数据多并且效果更明显,加入循环语句进行操作,给生产者线程和消费者线程分别加入循环语句(while循环)

改进之后出现两个问题:

1)同一个数据打印多次

//CPU一点点时间片足够执行很多次

2)并且年龄和姓名不符合

线程的随机性导致的

优化改进之后,这些问题就说明当前多线程有安全问题:

多线程安全问题的标准:

1)是否是多线程环境

2)是否有共享数据

3)是否有多条语句对共享数据操作

当前是多线程环境

有共享数据有多条语句对共享数据:s.name,s.age

使用同步机制来解决这个问题:将多条语句对共享数据进包装

使用同步机制去解决线程的安全问题,但是又有一个新的问题:

测试的时候,数据打印一打一大片,体验不好

需求:

让这个数据依次进行打印控制台,要使用这种方式去解决,利用Java等待唤醒机制

public class StudentDemo {
	public static void main(String[] args) {
		//创建一个资源对象
		Student s = new Student() ;
		//创建资源对象
		SetThread st = new SetThread(s) ;
		GetThread gt = new GetThread(s) ;
		//创建线程类对象
		Thread t1 = new Thread(st) ;
		Thread t2 = new Thread(gt) ;
		
		//分别启动线程
		t1.start() ;
		t2.start() ;
	}
}

public class Student {
	String name;
	int age ;
	//声明一个变量
	boolean flag ; //默认没有数据,如果true,则说明有数据
}




//生产者线程
public class SetThread implements Runnable {
	private Student s ;
	public SetThread(Student s){
		this.s = s ;
	}
	private int x = 0 ;
	public void run() {
		while(true){
			//同步机制进行操作
			synchronized (s) {
				//判断有没有数据
				if(s.flag){
					//处于等待状态
					try {
						s.wait() ;//阻塞式方法,立即释放锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				if(x%2==0){
					//x = 0 
					//设置数据
					s.name = "RNG" ; 
					s.age = 666;
				}else{
					
					//设置数据
					s.name = "EDG" ;
					s.age =233 ; 
				}
				x ++ ;
				//修改标记
				s.flag = true ;//有数据了
				//通知t2:消费者线程来消费数据
				s.notify() ;//唤醒等待这种状态...
			}
			
		}
		
	}

}

//消费者线程
public class GetThread implements Runnable {
	private Student s ;
	public GetThread(Student s){
		this.s = s ;
	}
	public void run() {
		while(true){
			synchronized (s) {
				//判断有没有数据
				if(!s.flag){
					try {
						s.wait() ;//调用的时候,会立即释放锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				//输出语句
			System.out.println(s.name+"---"+s.age);
			
				//修改标记
				s.flag = false ;//消费者线程
				//通知对方(t1线程),消费者线程没有数据类,赶紧来消费
				s.notify() ;//唤醒t1线程....
			}
			
		}
		
	}

}


线程组
线程组表示一个线程的集合:Java允许一个线程中有多个线程
public class ThreadGroupDemo {
	public static void main(String[] args) {
		method1() ;
		method2() ;
	}
	//给每一个子线程可以设置线程名称
	private static void method2() {
	
//public ThreadGroup(String name)构造一个新线程组
		ThreadGroup tg = new ThreadGroup("这是一个新的线程组") ;
		//创建线程类对象,并且将线程组对象作为参数进行传递,就使用Thread类的构造方法
		//public Thread(ThreadGroup group,Runnable target ,String name){}
		//创建资源对象
		MyRunnable my = new MyRunnable() ;
		Thread t1 = new Thread(tg, my, "线程1") ;
		Thread t2 = new Thread(tg, my, "线程2") ;
		
		ThreadGroup tg1 = t1.getThreadGroup() ;
		ThreadGroup tg2 = t2.getThreadGroup() ;
		
		System.out.println(tg1.getName());
		System.out.println(tg2.getName());
		tg.setDaemon(true) ;//将线程组中的所有的线程都设置为守护线程(后台线程)
	}

	private static void method1() {
		//如何获取多个线程所在的线程组名称呢?
		//创建资源对象
		MyRunnable my = new MyRunnable() ;
		//创建线程类对象
		Thread t1 = new Thread(my) ;
		Thread t2 = new Thread(my) ;
		
		t1.start() ;
		t2.start() ;
		
//public final ThreadGroup getThreadGroup()返回该线程所属的线程组
		ThreadGroup tg1 = t1.getThreadGroup() ;
		ThreadGroup tg2 = t2.getThreadGroup() ;
		
		//public final ThreadGroup getThreadGroup()返回该线程所属的线程组
		String name1 = tg1.getName() ;
		String name2 = tg2.getName() ;
		
		//子线程默认的线程组名称:main线程
		System.out.println(name1);
		System.out.println(name2);
		//所有的线程它的默认线程组名称就是main
		System.out.println(Thread.currentThread().getThreadGroup().getName());
		
	}
}

线程池的好处:节约成本,

很多子线程调用完毕不会立即被回收掉,而是会回到线程池中被多次利用

JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法

public static ExecutorServicenewFixedThreadPool(int nThreads)

Executors工厂类中的这个方法参数直接指定在当前线程池中有多少个线程

这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。它提供了如下方法

                   ExecutorsService:接口中的方法

                   Future<?>submit(Runnable task)

                   <T>Future<T> submit(Callable<T> task)

import java.util.concurrent.Executors;
import java.util.concurrent.Executors;
public class ExecutorsDemo {
	public static void main(String[] args) {
		//创建线程池对象,使用Executors工厂类
//public static ExecutorService newFixedThreadPool(int nThreads)
		ExecutorService pool = Executors.newFixedThreadPool(2) ;
		//下来使用ExecutorService(跟踪多个异步任务)一些方法
		
		//使用submit(Runnable target):提交多个任务
		pool.submit(new MyRunnable()) ;
		pool.submit(new MyRunnable()) ;
		
		//结束线程池
		pool.shutdown() ;
		
		
	}
}


public class MyRunnable implements Runnable {
	public void run() {
		//for循环
		for(int x = 0 ; x < 100 ; x ++){
			System.out.println(Thread.currentThread().getName()+":"+x);
		}7
	}

}

多线程程序的实现方式3:(实际开发中很少用到!)

public static ExecutorServicenewFixedThreadPool(int nThreads)

Executors工厂类中的这个方法参数直接指定在当前线程池中有多少个线程

这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnabl e对象或者Callable对象代表的线程。它提供了如下方法

                   ExecutorsService:接口中的方法

                   <T>Future<T> submit(Callable<T> task)

                   该返回值表示:异步计算的结果!

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CallableDemo {
	public static void main(String[] args) {
		//创建线程池对象,利用工厂类
		ExecutorService Threadpool = Executors.newFixedThreadPool(2) ;
		
		//提交Callable任务(异步任务)
		Threadpool.submit(new MyCallable()) ;//相当于线程中的start()方法
		Threadpool.submit(new MyCallable()) ;
		
		//结束线程池
		Threadpool.shutdown() ;
	}
}



import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableDemo {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//创建线程池对象,利用工厂类:Executors
		ExecutorService ThreadPool = Executors.newFixedThreadPool(2) ;
		
		//提交2异步任务,分别计算1-100,1-200之间的和
		Future<Integer> f1 = ThreadPool.submit(new MyCallable(100)) ;
		Future<Integer> f2 = ThreadPool.submit(new MyCallable(200)) ;
		
		//分别调用Future接口中  get()方法,返回具体的结果
		Integer v1 = f1.get() ;
		Integer v2 = f2.get() ;
		
		//输出结果
		System.out.println("v1:"+v1);
		System.out.println("v2:"+v2);
	}
}

import java.util.concurrent.Callable;
//线程求和
public class MyCallable implements Callable<Integer> {
	private int number ;
	public MyCallable(int number){
		this.number = number ;
	}
	public Integer call() throws Exception {
		//定义最终结果变量
		int sum = 0 ;
		for(int x = 1 ; x <=number;  x ++ ){
			sum += x ;
		}
		return sum;
	}

多线程中匿名内部类的方式

格式:new 类名(具体类,抽象类),接口(){

 重写/实现方法;

}

 匿名内部类的本质:

 继承了该类或者是实现该接口的子类对象

public class ThreadDemo {
	public static void main(String[] args) {
		//继承自Thread类
		new Thread(){
			public void run() {
				//for循环
				for(int x = 0 ; x <100 ; x ++){
					System.out.println(Thread.currentThread().getName()+":"+x);
				}
			}
		}.start() ;//启动线程
		
		
		//Runnable接口的方式
		new Thread(new Runnable() {
			public void run() {
				//for循环
				for(int x = 0 ; x < 100 ; x ++){
					System.out.println(Thread.currentThread().getName()+":"+x);
				}
			}
		}).start() ;
		
		
		new Thread(new Runnable() {
			public void run() {
				for(int x = 0 ; x <100 ; x ++){
					System.out.println("hello"+x);
				}
			}
		}){
			public void run() {
				for(int x = 0 ; x <100 ; x ++){
					System.out.println("world"+x);
				}
			}
		}.start() ;
	}
}

定时器:Timer:

常用的几个方法:

public void schedule(TimerTask task,Datetime)安排在指定的时间执行指定的任务

public void schedule(TimerTask task, longdelay)在多少毫秒后执行指定任务

public void schedule(TimerTask task, longdelay, long period)

在多少毫秒后,执行任务,并且每个多少毫秒重复执行

public void cancel()终止此计时器,丢弃所有当前已安排的任务

//需求:3秒后执行爆炸任务

import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
         publicstatic void main(String[] args) {
                   //publicTimer()创建一个新计时器。
                   Timert = new Timer() ;
                   //调用public voidschedule(TimerTask task, long delay)在多少毫秒后执行指定任务
                   //TimerTask:需要被执行的任务类是一个抽象类,所以不能直接实例化
                   t.schedule(newMyTask(t), 3000) ;
         }
}
 
//定义一个任务类:MyTask
//TimerTask中的一个抽象方法:public abstractvoid run():执行定时器的任务
class MyTask extends TimerTask{  
         privateTimer t ;
         publicMyTask(){
                  
         }
        
         publicMyTask(Timer t){
                   this.t= t ;
         }
                   publicvoid run() {
                   System.out.println("bom,爆炸了...");
                   t.cancel();//取消任务...
         }
        
}

public void schedule(TimerTask task, longdelay, long period)

在多少毫秒后,执行任务,并且每个多少毫秒重复执行

 需求:3秒后执行爆炸任务,每隔2秒重复爆炸

import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo2 {
	public static void main(String[] args) {
		//创建定时器对象
		Timer t = new Timer() ;
		//调用方法
		t.schedule(new MyTask2(), 3000, 2000) ;
	}
}
class MyTask2 extends TimerTask {
	public void run() {
		System.out.println("bom,爆炸了....");
	}
	
}


课堂练习

 需求:在指定的时间删除我们的指定目录
mport java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
//删除的demo文件夹的任务
class DeleteFolder extends TimerTask{
	public void run() {
		//封装当前项目下的这个demo文件
		File srcFolder = new File("demo") ;
		deleteFolder(srcFolder) ;
	}
	
	//递归删除
	private void deleteFolder(File srcFolder) {
		//获取当前srcFolder下面的所有的文件以及文件夹的File数组
		File[] fileArray = srcFolder.listFiles() ;
		//对该对象非空判断
		if(fileArray !=null){
			//增强for遍历
			for(File file :fileArray){
				//继续判断file对象是否是文件夹
				if(file.isDirectory()){
					//继续回到删除目录的方法
					deleteFolder(file) ;
				}else{
					//不是目录,是文件,直接删除
					System.out.println(file.getName()+"---"+file.delete());
				}
			}
			System.out.println(srcFolder.getName()+"----"+srcFolder.delete());
		}
	}
	
}
public class TimerTest {
	public static void main(String[] args) throws ParseException {
		//创建一个定时器对象
		Timer t = new  Timer() ;
		//public void schedule(TimerTask task,Date time)安排在指定的时间执行指定的任务
		//定义一个文本日期格式
		String dateStr = "2017-12-7 23:50:00" ;
		//解析成Date对象
		//创建SimpleDateFormat对象
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
		//解析方法
		Date date = sdf.parse(dateStr) ;
		//调用定时器的这个在规定时间内执行某个任务的方法
		t.schedule(new DeleteFolder(), date) ;
	}
}

课堂练习用户的注册登录

public class User {
	//声明两个成员变量
	private String username;
	private String password ;
	
	public User(){}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}



import org.westos.user.User;
//用户的操作接口层
public interface UserDao {
	//用户登录
	public abstract boolean isLogin(String username,String password) ;
	
	
//这是用户注册功能
	public abstract void regist(User user) ;
}






import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import org.westos.dao.UserDao;
import org.westos.user.User;

 // 这是用户操作的接口实现类(IO版)
public class UserDaoImpl implements UserDao {
	//在成员变量位置使用File对象封装这个文件
	private static  File file = new File("user.txt") ;
	
	static{
		try {
			file.createNewFile() ;
		} catch (IOException e) {
//			e.printStackTrace();
			System.out.println("创建文件失败....");
		}
	}
	
	//登陆功能
	public boolean isLogin(String username, String password) {
		//定义一个标记
		boolean flag = false ;
		
		///创建字符输入流,读取该文件中的内容
		BufferedReader br = null ;
		try {
		    br = new BufferedReader(new FileReader(file)) ;
			//一次可以读取一行
			String line = null ;
			while((line=br.readLine())!=null){
				//刚才注册的时候是:用户名=密码写入的
				String[] datas = line.split("=") ;
				if(datas[0].equals(username) && datas[1].equals(password)){
					//登陆成功,修改标记
					flag = true ;
				}
			}
		} catch (FileNotFoundException e) {
//			e.printStackTrace();
			System.out.println("用户登陆时找不到文件导致失败");
		} catch (IOException e) {
//			e.printStackTrace();
			System.out.println("用户登陆失败...");
		}finally{
			//释放资源
			if(br!=null){
				try {
					br.close() ;
				} catch (IOException e) {
//					e.printStackTrace();
					System.out.println("用户登陆时释放资源失败...");
				}
			}
		}
		return flag;
		
		
	}
	
	 //用户注册:
	// 必须约定以什么样的格式注册,使用流的形式将用户的用户名和密码输出到一个文件中,文件中就保存了用户名和用户密码,等会用户登录的时候只需要读取这个文件中内容就可以了
	public void regist(User user) {
		//注册的时候使用:字符缓冲输出流
		//使用构造方式,追加写入
		BufferedWriter bw = null ;
		try {
		   bw = new BufferedWriter(new FileWriter(file, true)) ;
			//应该约定一种格式:用户名=密码
			bw.write(user.getUsername()+"="+user.getPassword()) ;
			//刷新缓冲区
			bw.flush() ;
			bw.newLine() ;
		} catch (IOException e) {
//			e.printStackTrace();
			System.out.println("用户注册失败");
		}finally{
			//是否资源
			//针对流对象进行判断,是否为空
			if(bw !=null){
				try {
					bw.close() ;
				} catch (IOException e) {
//					e.printStackTrace();
					System.out.println("用户注册释放资源失败...");
				}
			}
		}
	}

}





import java.util.Scanner;

import org.westos.dao.UserDao;
import org.westos.dao.impl.UserDaoImpl;
import org.westos.user.User;

 //用户登陆注册的测试类

public class UserTest {

	public static void main(String[] args) {
		//为了能够回到这个界面
		while(true){
			//选择界面
			System.out.println("------------------欢迎光临---------------------");
			System.out.println("1 登陆");
			System.out.println("2 注册");
			System.out.println("3 退出");
			
			//创建键盘录入对象
			Scanner sc = new Scanner(System.in) ;
			
			//调用功能:
			UserDao ud = new UserDaoImpl() ;
			System.out.println("请您输入您的选择:");
			String choiceString = sc.nextLine() ;
			
			//使用选择结构语句之switch语句
			switch(choiceString){
			case "1" :
				//登陆界面
				System.out.println("--------------登陆界面---------------");
				System.out.println("请输入用户名:");
				String username = sc.nextLine() ;
				System.out.println("请输入密码:");
				String password = sc.nextLine() ;
				
				//调用功能
				boolean flag = ud.isLogin(username, password) ;
				if(flag){
					System.out.println("登陆成功");
					//break:只是结束switch语句
					System.exit(0) ;//终止Java虚拟机
				}else{
					System.out.println("登陆失败,用户名或者密码输入错误,请重新输入...");
				}
				break ;
			
			case "2":
				//注册界面
				System.out.println("--------------注册界面---------------");
				System.out.println("请输入用户名:");
				String newUserName = sc.nextLine() ;
				System.out.println("请输入密码:");
				String newPassword = sc.nextLine() ;
				
				//创建用户对象,封装用户名和密码
				User u = new User() ;
				u.setUsername(newUserName) ;
				u.setPassword(newPassword) ;
				
				//调用功能
				ud.regist(u) ;
				System.out.println("恭喜您,注册成功");
				break ;
				
			case "3":
				//退出界面
			default:
				System.out.println("欢迎光临,下次再继续使用....");
				System.exit(0) ;
				break ;
			}
		}
		
	}
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值