多线程面试题1

题目:自定义容器,提供新增元素(add)和获取元素数量(size)方法。
启动两个线程。线程1向容器中新增10个数据。线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止。

 ===============================================================================================

 使用三种方法:volatile,    synchronized,    CountDownLatch(门闩)

===============================================================================================

1.使用volatile修饰容器,只能保证容器数据的可见性保证不了完整性

public class TestBinFa2  {
	public static void main(String[] args) {
		final Test_01_Container t = new Test_01_Container();
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i = 0; i < 50; i++){
					System.out.println(" ");
					System.out.println("前=======>"+t.container.toString());
					t.add(new Integer(i));
					System.out.println("后=======>"+t.container.toString());
					try {
						TimeUnit.SECONDS.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		new Thread(new Runnable(){
			@Override
			public void run() {
				while(true){
					try {
						TimeUnit.SECONDS.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("长度为=========>"+t.size());
					if(t.size() == 45){
						System.out.println("长度为=========>"+t.size()+"线程2中断了=======");
						break;
					}
				}
			}
		}).start();
	}
}
class Test_01_Container{
	volatile List<Integer> container = new ArrayList<>();
	public /*synchronized*/ void add(int num){
		this.container.add(num);
	}
	public /*synchronized*/ int size(){
		return this.container.size();
	}
}

2.synchronized能保证数据的同步和并发,

public class TestBinFa3  {
	public static void main(String[] args) {
		final Test_01_Container1 t = new Test_01_Container1();
		final Object lock = new Object();
		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (lock) {
					for(int i = 0; i < 10; i++){
						
						System.out.println(" ");
						System.out.println("前=======>"+t.container.toString());
						t.add(new Integer(i));
						System.out.println("后=======>"+t.container.toString());
						if(t.size()==5){
							lock.notifyAll();
							try {	
								
								lock.wait();
								Thread.sleep(500);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		}).start();
		
		new Thread(new Runnable(){
			@Override
			public void run() {
				synchronized (lock) {
					while(true){
							System.out.println("长度为=========>"+t.size());
							if(t.size() != 5){
								try {
									lock.wait();////当前线程进入等待
									Thread.sleep(500);
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
							System.out.println("长度为=========>"+t.size()+"被中断");
							lock.notifyAll();
							break;
							
					}
				}
			}
		}).start();
	}
}

class Test_01_Container1{
	 List<Integer> container = new ArrayList<>();
	
	public  void add(int num){
		this.container.add(num);
	}
	
	public  int size(){
		return this.container.size();
	}
}

3.使用门闩的方法,当add完后长度为5,就释放门闩,减掉门闩使其开放,

当检测长度不为5则等待门闩,

public class TestBinFa4  {
	public static void main(String[] args) {
		final Test_01_Container2 t = new Test_01_Container2();
		final CountDownLatch latch = new CountDownLatch(1);
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i = 0; i < 10; i++){
					System.out.println(" ");
					System.out.println("前=======>"+t.container.toString());
					t.add(new Integer(i));
					System.out.println("后=======>"+t.container.toString());
					if(t.size()==5){
						latch.countDown();////////释放门闩的
						try {	
							Thread.sleep(500);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}).start();
		
		new Thread(new Runnable(){
			@Override
			public void run() {
					while(true){
						System.out.println("长度为=========>"+t.size());
						if(t.size() != 5){
							try {
								latch.await();////等待门闩个数为0就能往下运行。
								Thread.sleep(500);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						System.out.println("长度为=========>"+t.size()+"被中断");
						break;
					}
			}
		}).start();
	}
}
class Test_01_Container2{
	 List<Integer> container = new ArrayList<>();
	public  void add(int num){
		this.container.add(num);
	}
	public  int size(){
		return this.container.size();
	}
}

 

内容概要:本文是一篇关于使用RandLANet模型对SensatUrban数据集进行点云语义分割的实战教程,系统介绍了从环境搭建、数据准备、模型训练与测试到精度评估的完整流程。文章详细说明了在Ubuntu系统下配置TensorFlow 2.2、CUDA及cuDNN等深度学习环境的方法,并指导用户下载和预处理SensatUrban数据集。随后,逐步讲解RandLANet代码的获取与运行方式,包括训练、测试命令的执行与参数含义,以及如何监控训练过程中的关键指标。最后,教程涵盖测试结果分析、向官方平台提交结果、解读评估报告及可视化效果等内容,并针对常见问题提供解决方案。; 适合人群:具备一定深度学习基础,熟悉Python编程和深度学习框架,从事计算机视觉或三维点云相关研究的学生、研究人员及工程师;适合希望动手实践点云语义分割项目的初学者与进阶者。; 使用场景及目标:①掌握RandLANet网络结构及其在点云语义分割任务中的应用;②学会完整部署一个点云分割项目,包括数据处理、模型训练、测试与性能评估;③为参与相关竞赛或科研项目提供技术支撑。; 阅读建议:建议读者结合提供的代码链接和密码访问完整资料,在本地或云端环境中边操作边学习,重点关注数据格式要求与训练参数设置,遇到问题时参考“常见问题与解决技巧”部分及时排查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值