多线程常用知识点

多线程并发执行可以提高程序的效率,同时完成多项工作。
多线程的应用场景:迅雷下载多个资源,服务器处理多个请求,qq多人视频。
并行需要多核cpu,并发不需要。

java程序的运行原理:
java命令会启动jvm虚拟机,等于启动了一个进程(应用程序)。该进程会启动一个主线程,主线程去调用入口类的main方法。
jvm至少启动了主线程和垃圾回收线程,所以是多线程的。

多线程程序实现的两种方式:
1.继承Thread类
public class ThreadTest2 extends Thread {
    private int threadCnt = 10;

    @Override
    public void run() {
        while (true) {
            if (threadCnt > 0) {
                System.out.println(Thread.currentThread().getName() + " 剩余个数 " + threadCnt);
                threadCnt--;
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        new ThreadTest2().start();
        new ThreadTest2().start();
    }
}
2.实现runnable方法
public class RunnalbleTest2 implements Runnable {
    private int threadCnt = 10;

    @Override
    public void run() {
        while (true) {
            if (threadCnt > 0) {
                System.out.println(Thread.currentThread().getName() + " 剩余个数 " + threadCnt);
                threadCnt--;
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        RunnalbleTest2 runnalbleTest2 = new RunnalbleTest2();
        new Thread(runnalbleTest2).start();
        new Thread(runnalbleTest2).start();
        new Thread(runnalbleTest2).start();
        new Thread(runnalbleTest2).start();
    }
}

实现runnable的原理(查看源码可知):
1.Thread类的构造函数传递了runnable接口的引用,将实现的类传入了构造方法当参数。
2.构造方法调用init方法,用实现的类给成员变量target赋值。
3.run方法中调用了实现类的(target的)run方法。
4.thread的start方法调用了run方法。

两种创建线程的方式的区别
1.从代码的角度看,继承thread是调用start方法时直接找子类的run方法,实现runnable是start方法先调用thread的run方法,再通过父类引用指向子类的原理调用作为参数的子类的run方法。
2.从使用的角度看,继承thread代码简单,但有父类就不能用了。实现runnable代码复杂,但有父类也没关系。

匿名内部类实现多线程的两种方式(不需要创建类):
public class Demo {
    public static void main(String[] args) {
        // 继承Thread类实现多线程
        new Thread("线程名字") {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName() + "--" + i);
                }
            }
        }.start();
        // 实现Runnable接口实现多线程
        new Thread(new Runnable() {

            public void run() {
                for (int i = 0; i < 100; i++) {
                    Thread.sleep(100)
                    System.out.println(Thread.currentThread().getName() + "--" + i);
                }
            }
        }) {
        }.start();
    }
}

spark解决数据倾斜可以用加随机前后缀的方式,可是如此一来key就失去了意义,怎么办???7月23日 02:53
spark是实时的,为什么shuffle的时候还会产生磁盘文件,而不是直接将单条或少数几条数据传送到下一个rdd?7月23日10:07
 1、实时处理也是需要在内存中计算数据的,内存不足的时候就内存溢出了。 所以实时处理 和 使用内存不冲突的
 2、修改key的情况是要根据业务设计的。  添加后缀是把原来一个分区的数据分到几个子分区处理,添加前缀会全部打散,这是一个解决问题的思路,具体问题还要具体分析7月23日 10:10
 3、内存不足的时候,spark中的数据是会刷到磁盘上面的,RDD的弹性主要说的就是这个特点

匿名内部类多线程获取和设置线程名字:
this.getName()
this.setName()
非匿名内部类:
t.setName()
t.start()

获取当前线程对象:
Thread.currentThread()

休眠线程:
Thread.sleep(毫秒值)

守护线程:setDaemon() 设置一个线程为守护线程,该线程不会单独执行,当其他的非守护线程都执行完毕后,自动退出。
t.setDaemon(true)
t.start()

加入线程:
t.join()让t线程插队先执行
t.join(100)让t线程插队先执行100ms再交替执行

礼让线程:
Thread.yield() 让出cpu(很多时候达不到效果)

设置线程的优先级:
t.setPriority()设置优先级,默认是5,最小是1,最大是10

同步代码块:
什么情况下需要同步:当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中cpu不要切换到其他的线程,这时就需要同步。
如果两段代码是同步的,那么同一时间只能执行其中的一段。
使用synchronized关键字加上一个锁对象来定义一段代码,就叫同步代码块。
多个同步代码块如果使用相同的锁对象,那他们就是同步的。
锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,因此不能使用匿名对象。

同步方法:
使用synchronized关键字修饰一个方法,该方法中的所有代码都是同步的。
public synchronized void xxx
非静态同步方法的锁对象是this
静态同步方法的锁对象是该类的字节码对象

懒汉式的单例多线程访问时有线程安全隐患,饿汉(开发时使用该方式)的没有。饿汉式是空间换时间。

单例模式的应用举例:RunTime类RunTime.getRunTime()返回当前程序的运行时对象

Timer类:计时器,在指定的时间做指定的事(原理就是开启一个线程)。
Timer.schedule()

public class MyTimerTask extends TimerTask {
 
    @Override
    public void run() {
        System.out.println("Timer task started at:"+new Date());
        System.out.println("Timer task finished at:"+new Date());
    }
    }

TimerTask timerTask = new MyTimerTask();
Timer timer = new Timer();
timer.schedule(timerTask, 0, 10*1000);

(run方法中的异常只能处理,因为父类不抛异常子类就不能抛异常)

两个线程之间的通信:wait()等待,notify()唤醒
在同步中,锁设置为什么,就用什么调用wait和notify。假如多个方法使用同一个锁(同步代码块),那就随机唤醒他们中的一个
wait方法和notify方法定义在了Object类里面,因为他是所有类的父类

sleep和wait方法的区别:sleep必须传入参数,时间到了自动醒来。wait传不传参数都行,传入参数就是多长时间之后开始等待,不传参数就是立即等待;
sleep方法在同步函数或代码块中不释放锁,wait释放锁

jdk1.5的新特性互斥锁:
同步:使用ReentrantLock的lock()和unlock()方法进行同步
通信:使用ReentrantLock的newCondition()方法可以获取condition对象。
等待用condition的await(),唤醒用signal()方法。
不同的线程使用不同的condition,就能区分唤醒哪个线程了。

线程组:(默认情况下都属于主线程组main)
t.getThreadGroup().getName()获取某线程的线程组对象的名字

Runnable方式指定线程的线程组和线程名字:
ThreadGroup th = new ThreadGroup("线程组名");
MyRunnable mr = new MyRunnable();
Thread t = new Thread(th,mr,"线程名字");

线程的五种状态(生命周期):新建,就绪(有执行资格,没执行权),执行(有,有),阻塞(无,无),死亡。阻塞必须先变成就绪才能变成执行。

线程池:
 创建线程成本高,因为涉及到与操作系统进行交互。jdk5开始java内置线程池,之前需要手动实现。
 Executors工厂类生产线程池,方法有newFixedThreadPool(int),newSingleThreadExecutor(),这些方法返回ExecutorService对象,表示线程池,可以执行Runable对象或Callable对象代表的线程。
 他提供了submit(Runnable task)和submit(Callable<T> task)
使用线程池的步骤:创建线程池对象,创建runnable实例,提交runnable实例,关闭线程池shutdown()


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值