javase进阶之多线程

图神经网络实战(25)——基于A3T-GCN预测交通流量 本节重点讨论了使用 TGNN 进行交通预测任务。首先,我们介绍了 PeMS-M 数据集,并将其从表格数据转换为具有时间信号的静态图数据集。在实践中,我们根据输入距离矩阵创建了加权邻接矩阵,并将交通速度转换为时间序列。最后,我们构建了 A3T-GCN 模型,这是一个专为交通预测设计的 T-GNN 模型,并将结果与两个基线模型进行了比较,验证了模型的预测结果。 阅读详情

目标

  1. 了解线程和进程的关系
  2. 了解线程并发执行的原理
  3. 熟练使用两种方式创建线程
  4. 理解同步机制(锁)。

多线程学习的路径

理解什么是线程 -> 线程的基本使用 -> 理解并使用同步 -> 学习并掌握JUC -> 理解线程执行的底层逻辑

一:线程的概念

进程与线程的关系

进程:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。

线程:是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

多线程 执行原理 ( 并发执行原理 )

CPU核心: 每一个计算机中CPU核心, 就相当于人的一个大脑, 可以执行一件事情。

时间片: 将CPU未来可以用于执行的时间 ,碎片化, 拆分成一个个的小的时间片段. 每一个时间片段的大小 可以都不足一毫秒,程序在争抢到时间片段后, 会进行执行 。

线程创建的三种方式

Demo01.线程创建的方式一 继承Thread

Demo02.线程创建的方式二 实现Runnable

Demo03.线程创建的方式三 方式一的简写格式,通过匿名内部类的方式继承Thread

package com.kkb;

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i =0;i<1000;i++){
            System.out.println("runnable:"+i);
        }
    }
}

Demo01.线程创建的方式一 继承Thread  

package com.kkb;

public class Demo01 {
    static class MyThread1 extends Thread{
        @Override
        public void run() {
            heihei("小红");
        }
    }
    public static void main(String[] args) {
        Thread t = new MyThread1();
        t.start();
        heihei("小明");
    }
    public static void heihei(String text){
        for (int i=0;i<1000;i++){
            System.out.println(text+": i="+i);
        }
    }
}

Demo02.线程创建的方式二 实现Runnable  

package com.kkb;

public class Demo02 {
    public static void main(String[] args) {
        MyRunnable run =new MyRunnable();
        Thread t = new Thread(run);
        t.start();
        for (int i =0;i<1000;i++){
            System.out.println("main:"+i);
        }
    }
}

Demo03.线程创建的方式三 方式一的简写格式,通过匿名内部类的方式继承Thread 

package com.kkb;

public class Demo03 {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                for (int i=0;i<1000;i++){
                    System.out.println("t: "+i);
                }
            }
        }.start();
        for (int i=0;i<1000;i++){
            System.out.println("m: "+i);
        }
    }
}

Thread 类 常用方法 

常用的静态方法

静态方法作用于,调用的线程。

- static void sleep(int 毫秒数) ***

此方法执行时 所在的线程睡眠 , 用于降低线程的活跃度 .

- static Thread currentThread();

获取此方法执行时 所在线程的 线程对象.

- static void yield();

此方法执行时所在的线程, 让出当前时间片. 用于降低线程的活跃度

package com.kkb;

public class Demo04 {
    public static void main(String[] args) throws Exception {
        Thread t =new Thread(){
            @Override
            public void run() {
                for (int i=0;i<1000;i++){
                    System.out.println(Thread.currentThread().getName()+":t="+i);
                };
            }
        };
        t.setName("新线程");
        t.start();
        for (int i=0;i<1000;i++){
            //降低线程活跃度,让它一秒打印一次
            //Thread.sleep(1000);
            //让出时间片
            Thread.yield();
            System.out.println(Thread.currentThread().getName()+":m="+i);
            Thread.yield();
        }
    }
}

- 常用的非静态方法

- void start() ***

启动此线程所表示的线程对象, 并在新的线程中执行run方法

- void setName(String name) | String getName(); 了解

设置/获取 线程名称; 线程拥有默认的名称

- stop() 了解

停止线程(已过时 , 不建议使用, 因为会造成固有的不安全性);

- interrupt() 了解

中断线程!

此方法用于在某一个线程上 加入 中断标记.

这个线程被加入标记后, 它正在执行的逻辑,如果触发一些特殊的方法, 会出现异常 !

通常此操作用于通知线程停止 . 具体是否停止, 由线程自身决定.

package com.kkb;

public class Demo05 {
    public static void main(String[] args) {
        Thread t1 =new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {//中断异常
                        //e.printStackTrace();会报错,但程序不会仍旧继续
                        //中断线程,杀死线程最合法的方式,stop方法不安全
                        break;
                    }
                    System.out.println("i="+i);
                }
            }
        };
        t1.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t1.interrupt();
    }
}

守护线程

- setDaemon(boolean flag) 了解

传入true设置线程为守护线程 ! 默认一个线程为用户线程 .

线程共分为两大类

1. 用户线程

通常情况下, 我们自己开启的线程都是用户线程, 所有的用户线程都是一条单独的执行路径, 一个软件的所有用户线程执行完毕, 程序会死亡 .

2. 守护线程

程序中存在一种特殊的线程, 叫做守护线程, 可以理解为 : 守护用户线程 .

当程序中所有的用户线程都死亡了. 守护线程无论是否执行完毕, 都会自动死亡.

Java中的垃圾回收器 GC 其实就是守护线程.

package com.kkb;

public class Demo06 {
    public static void main(String[] args) {
        Thread Liming = new Thread(){
            @Override
            public void run() {
                for (int i=0;i<60;i++){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("黎明:嗯哼哈嘿。。。");
                }
                System.out.println("黎明完事走了。");
            }
        };
        Thread Dage = new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("大哥:望风中。。。");
                }
            }
        };
        Dage.setDaemon(true);
        Liming.start();
        Dage.start();
    }
}

 线程的优先级

- setPriority(int 优先级) 了解

线程优先级: 取值1-10 , 表示线程的10个优先等级. 10最高 1最低

优先级的作用是: 让线程更有可能争抢到时间片 .

系统提供了建议使用的三种值:

1: 较低的优先级

5: 中等的优先级

10: 较高的优先级

package com.kkb;

public class Demo07 {
    public static void main(String[] args) {
        MyThread m1=new MyThread();
        MyThread m2=new MyThread();
        MyThread m3=new MyThread();
        m1.setPriority(1);
        m1.setName("低优先级");
        m2.setPriority(5);
        m2.setName("中优先级");
        m3.setPriority(10);
        m3.setName("高优先级");
        m1.start();
        m2.start();
        m3.start();
    }
    static class MyThread extends Thread{
        @Override
        public void run() {
            for (int i=0;i<100;i++){
                System.out.println(getName()+":"+i);
            }
        }
    }
}

注意: 调整一个线程的优先级, 并不能保证一个线程绝对能争抢到时间片, 只是几率大了一丢丢 !

1和10的区别大概可以理解为: 50% 和51%

线程默认优先级

一个线程的默认优先级 与 启动它的线程完全一致 ;

main线程的优先级为5

线程的生命周期

 

1.创建

Plain Text

public class MyThread extends Thread{

@Override

public void run() {

//...

}

}

//新建就是new出对象

MyThread thread = new MyThread();

当程序使用new关键字创建了一个线程之后,该线程就处于一个新建状态(初始状态),此时它和其他Java对象一样,仅仅由Java虚拟机为其分配了内存,并初始化了其成员变量值。此时的线程对象没有表现出任何线程的动态特征,程序也不会执行线程的线程执行体。

2.就绪

当线程对象调用了Thread.start()方法之后,该线程处于就绪状态。

Java虚拟机 会为其创建方法调用栈和程序计数器,处于这个状态的线程并没有开始运行,它只是表示该线程可以运行了。从start()源码中看出,start后添加到了线程列表中,接着在native层添加到VM中,至于该线程何时开始运行,取决于JVM里线程调度器的调度(如果OS调度选中了,就会进入到运行状态)。

3.运行

当线程对象调用了Thread.start()方法之后,该线程处于就绪状态。

添加到了线程列表中,如果OS调度选中了,就会进入到运行状态

4.阻塞

阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况大概三种:

  • 1、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
  • 2、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
  • 3、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)。
  • 线程睡眠:Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好。
  • 线程等待:Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。这个两个唤醒方法也是Object类中的方法,行为等价于调用 wait(0) 一样。唤醒线程后,就转为就绪(Runnable)状态。
  • 线程让步:Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。
  • 线程加入:join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。
  • 线程I/O:线程执行某些IO操作,因为等待相关的资源而进入了阻塞状态。比如说监听system.in,但是尚且没有收到键盘的输入,则进入阻塞状态。
  • 线程唤醒:Object类中的notify()方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程,选择是任意性的,并在对实现做出决定时发生。类似的方法还有一个notifyAll(),唤醒在此对象监视器上等待的所有线程。

5.死亡

线程会以以下三种方式之一结束,结束后就处于死亡状态:

  • run()方法执行完成,线程正常结束。
  • 线程抛出一个未捕获的Exception或Error。
  • 直接调用该线程的stop()方法来结束该线程——该方法会产生固有的不安全性,不推荐.

线程安全问题

同步即排队 . 异步即并行. 

当多个线程同时操作一段数据时,容易发生问题。

同步就是线程安全, 效率较低! 线程安全可以有效的结果 临界资源出错问题 !

异步表示线程非安全, 效率高

线程同步的两种实现方式

两种方式 都是通过 加锁 来完成同步操作的.

记住一点: 在同步代码块时 我们手动指定锁对象时 . 多个线程必须使用同一个锁 ,才可以完成同步操作 !

同步代码块

Plain Text

格式:

synchronized(Object 锁对象){

}

package com.kkb;
//同步:排队 多线程排队执行
//异步:并行 多线程同时执行
public class Demo08 {
    public static int count =10;
    //创建锁对象
    static Object o =new Object();
    public static void haha(){
        synchronized (o){
            if (1==1){}
        }
    }
    public static void heihei(){
        synchronized (o){//同步代码块
            if (count > 0) {
                System.out.println("余票充足,卖票中...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("卖票成功,余票:" + --count);
            } else {
                System.out.println("余票不足,很遗憾");
            }
        }
    }
    public static void main(String[] args) {
        //线程一
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    heihei();
                }
            }
        }.start();
        //线程二
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    heihei();
                }
            }
        }.start();
        //线程三
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    heihei();
                }
            }
        }.start();
    }
}

同步方法

非静态的同步方法的锁对象为this

静态方法的锁对象 , 是我们的类信息对象 (类名.class).

格式

权限修饰符 synchronized 返回值声明 方法名(形式参数列表){

}

package com.kkb;

public class Demo09 {
    public static int count =10;
    //创建锁对象
    static Object o =new Object();
    public static synchronized void heihei(){
        if (count > 0) {
            System.out.println("余票充足,卖票中...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("卖票成功,余票:" + --count);
        } else {
            System.out.println("余票不足,很遗憾");

        }
    }
    public static void main(String[] args) {
        //线程一
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    heihei();
                }
            }
        }.start();
        //线程二
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    heihei();
                }
            }
        }.start();
        //线程三
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    heihei();
                }
            }
        }.start();
    }
}

同步方法 与 同步代码块, 何时使用, 选择哪个?

同步代码块 粒度更小 . 更灵活 !

同步方法的操作 最小单位就是一个方法所有的 代码 .

同步方法因为默认使用了this作为锁对象. 所以它存在一个特殊的操作:

同一个对象中的 所有同步方法, 均使用this这一把锁, 所以可以达到 多方法同时上锁的需求 !

公平锁和不公平锁 

公平锁:多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁。

  • 优点:所有的线程都能得到资源,不会饿死在队列中。
  • 缺点:吞吐量会下降很多,队列里面除了第一个线程,其他的线程都会阻塞,cpu唤醒阻塞线程的开销会很大。

非公平锁:多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,如果能获取到,就直接获取到锁。

  • 优点:可以减少CPU唤醒线程的开销,整体的吞吐效率会高点,CPU也不必取唤醒所有线程,会减少唤起线程的数量。
  • 缺点:你们可能也发现了,这样可能导致队列中间的线程一直获取不到锁或者长时间获取不到锁,导致饿死。

 线程同步问题

package com.kkb;

public class Demo10 {
    public static void main(String[] args) {
        heihei h = new heihei();
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    //线程排队,静态方法用的是同一把锁
                    //heihei.heihei1();
                    //非静态方法的锁是this,this是同一个对象吗?
                    //答案是的,还是会排队
                    //h.heihei2();
                    //但如果用的不是一个对象,就不会排队了
                    new heihei().heihei2();
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                for (int i=0;i<10;i++){
                    //heihei.heihei1();
                    //h.heihei2();
                    new heihei().heihei2();
                }
            }
        }.start();
    }

    static int count = 0;
    static class heihei{
        // 静态的同步方法
        public static synchronized void heihei1(){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(count++);
        }
        // 非静态的同步方法
        public  synchronized void heihei2(){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(count++);
        }
    }
}

线程死锁

package com.kkb;

public class Demo11 {
    public static void main(String[] args) {
        //线程死锁
        Culprit c = new Culprit();
        Police p = new Police();
        new MyThread(c,p).start();
        c.say(p);
    }

    static class MyThread extends Thread{
        private Culprit c;
        private Police p;
        MyThread(Culprit c,Police p){
            this.c = c;
            this.p = p;
        }

        @Override
        public void run() {
            p.say(c);
        }
    }
    static class Culprit{
        //绑匪类
        public void say(Police p){
            System.out.println("绑匪:你放了我,我放人质");
            p.fun();
        }
        public void fun(){
            System.out.println("绑匪被放走了,也释放了人质");
        }
    }
    static class Police{
        //警察类
        public void say(Culprit c){
            System.out.println("警察:你放了人质,我放过你");
            c.fun();
        }
        public void fun(){
            System.out.println("警察救到了人质,也抓到了绑匪");
        }
    }
}

多线程通信问题, 生产者与消费者问题 

package com.kkb;

public class Demo12 {
    /**
     * 多线程通信问题, 生产者与消费者问题
     * @param args
     */
    public static void main(String[] args) {
        Food f = new Food();
        new Cook(f).start();
        new Waiter(f).start();
    }

    //厨师
    static class Cook extends Thread{
        private Food f;
        public Cook(Food f) {
            this.f = f;
        }

        @Override
        public void run() {
            for(int i=0;i<100;i++){
                if(i%2==0){
                    f.setNameAndSaste("老干妈小米粥","香辣味");
                }else{
                    f.setNameAndSaste("煎饼果子","甜辣味");
                }
            }
        }
    }
    //服务生
    static class Waiter extends Thread{
        private Food f;
        public Waiter(Food f) {
            this.f = f;
        }
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                f.get();
            }
        }
    }
    //食物
    static class Food{
        private String name;
        private String taste;

        //true 表示可以生产
        private boolean flag = true;

        public synchronized void setNameAndSaste(String name,String taste){
            if(flag) {
                this.name = name;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.taste = taste;
                flag = false;
                this.notifyAll();
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        public synchronized void get(){
            if(!flag) {
                System.out.println("服务员端走的菜的名称是:" + name + ",味道:" + taste);
                flag = true;
                this.notifyAll();
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

掌握 Unity 中的状态机:综合指南 最后,将拥有一个由状态机驱动的功能齐全的播放器控制器,可以集成到自己的项目中。此外,状态机有助于实现复杂的人工智能、玩家控制、动画系统等,从而形成更强大、更灵活的游戏架构。状态机是计算机科学和游戏开发中的一个基本概念,它通过定义一组有限的状态及其之间的转换来模拟实体的行为。你可以定义常见的状态行为,例如 Enter、Update 和 Exit 方法,确保整个状态机架构的一致性和连贯性。由于前面提到的状态类扩展了 BaseState 类,因此我们可以为具有不同状态的不同对象创建单独的类。 阅读详情

相关推荐

pytorch-cifar100学习资料汇总 - 基于PyTorch的CIFAR-100图像分类实践

pytorch-cifar100是一个基于PyTorch实现CIFAR-100数据集图像分类的开源项目。该项目实现了多种经典的深度学习网络模型,如ResNet、DenseNet、VGG等,为开发者提供了在CIFAR-100数据集上进行图像分类实验的代码范例。pytorch-cifar100项目为我们提供了在CIFAR-100数据集上进行图像分类实验的完整代码实现。无论你是想要学习PyTorch的使用,还是研究不同网络模型在CIFAR-100上的表现,这个项目都是一个很好的起点。

helloaiworld的博客 1123

Java continue语句

Java continue语句

m0_69505153的博客 315

AEB(自动紧急制动)

AEB系统对静止物体的误判率受多种因素影响,包括传感器精度、算法复杂性以及环境条件等。通过多传感器融合、算法优化、硬件升级以及环境适应性增强等技术手段,可以有效减少误判问题。美国和欧洲的AEB法规均强调了技术性能和安全性,但具体要求有所不同。美国的NHTSA规定更注重高速和复杂场景下的紧急制动能力,而欧盟的ECE R152法规则更侧重于基础的AEB功能覆盖范围。

百态·数智思维 | 聚焦大数据、量化与未来AI 2550

Java编程那些事儿99——多线程问题及处理2

Java编程那些事儿99——多线程问题及处理2陈跃峰出自:http://blog.youkuaiyun.com/mailbomb 如果这个例子还不能帮助你理解如何解决多线程的问题,那么下面再来看一个更加实际的例子——卫生间问题。         例如火车上车厢的卫生间,为了简单,这里只模拟一个卫生间,这个卫生间会被多个人同时使用,在实际使用时,当一个人进入卫生间时则会把卫生间锁上,等出来时

爪哇米工作室陈跃峰的移动开发博客 4001

SAP开发实战:用FI_DOCUMENT_CHANGE BAPI批量修改FB03凭证抬头和行项目文本(附完整ABAP代码)

本文详细介绍了如何使用SAP的FI_DOCUMENT_CHANGE BAPI批量修改FB03凭证抬头和行项目文本,提供完整的ABAP代码实现方案。通过该BAPI,开发者可以高效完成财务凭证的批量修改,确保数据一致性和审计合规性,显著提升SAP财务模块的运维效率。

weixin_29224589的博客 381

对称加密和非对称加密、公钥和私钥、单向认证和双向认证、数字签名、数字证书、根证书

文章目录1. 什么是公钥和私钥?2. 加密算法2.1 对称加密2.2 非对称加密2.2.1 非对称加密的重要性质2.2.2 非对称加密算法应用2.2.2.1 应用1 加密通信2.2.2.1.1 单向认证和双向认证2.2.2.1 应用2 数字签名3. 数字签名3.1 数字签名用法演示3.2 数字签名存在问题4. 数字证书(Digital Certificate)4.1 创建数字证书4.1.1 举例,CA如何给我们签发一个有效证书: 1. 什么是公钥和私钥? 摘自《什么是公钥和私钥?》 公钥(Public Ke

m0_45406092的博客 1万+

【Java编程教程】详解 Java continue 继续循环语句

因此,我们现在可以继续 Java 中的任何循环,无论是外循环还是内循环。当需要立即跳转到循环的下一次迭代时,在循环控制结构中使用 continue 语句。它可以与 for 循环或 while 循环一起使用。在内部循环的情况下,它仅继续内部循环。我们可以在所有类型的循环中使用 Java continue 语句,例如 for 循环、while 循环和 do-while 循环。正如您在上面的输出中看到的,5 没有打印在控制台上。只有在内循环中使用 continue 语句,它才会继续内循环。

jiangjun020326的博客 5692

微信H5网页授权通用方案:中转页破解域名限制,适配Hash/History路由

在Web开发中,OAuth 2.0授权码模式是实现第三方登录的通用标准,其核心原理是通过授权服务器颁发临时代码,再由客户端交换访问令牌。这一机制在微信公众号H5开发中尤为重要,用于安全获取用户身份。然而,微信平台对网页授权回调域名有严格的数量限制,这成为多子域名、多环境及微前端架构下业务扩展的主要瓶颈。其技术价值在于通过设计一个统一的中转授权页,将授权逻辑与业务逻辑解耦,让所有业务页面共享一个已配置的授权入口,从而突破域名配额限制。该方案的关键在于适配不同的前端路由模式,需精准处理Hash模式与Histor

weixin_42533120的博客 318

浅谈Java多线程的同步问题

多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问。 下面以一个简单的实例来进行对比分析。实例要完成的工作非常简单,就是创建10个线程,每个线程都打印从0到99这100个数字,我们希望线程之间不会出现交叉乱序打印,而是顺序地打印。 先来看第一段代码,这里我们在run()方法中加入了synchronized关键字,...

weixin_33721344的博客 259

基于SiamFC的红外目标跟踪

初始化阶段:在第一帧中,通过用户标注获得目标框,从目标区域中提取一个固定大小的模板(称为 exemplar)。搜索阶段:在后续帧中,在以当前目标中心为中心的较大区域(称为 instance)内进行搜索,将模板与搜索区域通过卷积操作得到响应图。位置更新:在响应图中找到峰值位置,并转换到原图坐标,用以更新目标中心。部分实现中还会考虑多尺度搜索和目标尺寸更新。import cv2# 定义 SiamFC 简易网络(示例)# 特征提取部分,注意红外图像通常为单通道,使用较少的卷积核数提高实时性。

weixin_43745234的博客 774

基于扩散模型的图像去噪与修复:原理、实现与性能分析【附核心代码】

扩散模型(Diffusion Models)在图像修复、去噪、风格化、超分辨率等领域的应用,展示了其强大的生成能力和灵活性。通过模拟图像逐步加噪声再去噪的过程,扩散模型不仅能够恢复图像的细节,还能生成高质量的图像。本文详细探讨了扩散模型在图像修复和增强中的应用,并通过具体代码示例展示了如何使用扩散模型进行去噪、风格化、图像超分辨率等任务。扩散模型在图像修复中通过逐步去噪修复损坏的区域,在图像去噪中则能够去除图像中的噪声并保留细节;在图像风格化中,扩散模型通过结合目标风格和内容生成富有艺术性的图像;

一键难忘的博客 2929

线程 continue -- 4

ThreadLocal 的性能虽然线程局部变量早已赫赫有名并被包括 Posix pthreads 规范在内的很多线程框架支持,但最初的 Java 线程设计中却省略了它,只是在 Java 平台的版本 1.2 中才添加上去。在很多方面,ThreadLocal 仍在发展之中;在版本 1.3 中它被重写,版本 1.4 中又重写了一次,两次都专门是为了性能问题。 在 JDK 1.2 中,ThreadLoca

J-CAREER BY WENSI 1358

硬方案——几种实用的恒流源电路设计方案,敬请收藏(运放、三极管在手,让你玩出多种花样)

0 引言 我们在信号测量、供电等应用场景时常会涉及到使用恒流源,以前觉得恒流源挺神奇的,研究了下实现方案,其实也没有多么高深(这里讨论的仅限于用在信号测量中的小电流恒流源设计),这里给出几个实用的恒流源电路设计方案。 1 恒流源电路设计 (1)使用三极管搭建的恒流源 (2)使用运放搭建的恒流源 (3)使用恒流二极管搭建的恒流源 pt100恒流源测温电路图_电子技术_电工之家 ...

数字世界 万物互联 9524

【JavaSE】【多线程】进阶知识

锁策略,synchronized特性,CAS,JUC组件

yj20040627的博客 4954

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

javaSE初阶————多线程进阶(2)

另外,记录的元素个数size怎么办呢,两个线程同时增加数据,size也会有线程安全问题,还有加锁吗,忘了我们的AtomicIngter了吗,这个原子类也是很好用的呀,大家不要忘了;我们之前学过Runnable接口,它是一个任务,我们可以在创建线程的时候把任务丢给线程使用匿名内部类等方法来完成创建对象,现在我们有了一个新的方法来创建任务,并且执行这个任务,就是我们的Callable接口,Runnable的run方法是没有返回值的,但是Callable提供了返回值,支持泛型,我们就能获取到我们想要的参数,

2301_79083481的博客 2679

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

JavaSE进阶(一)——多线程概述

JavaSE进阶(一)——多线程概述 前言 从本篇笔记开始我们进入到JavaSE进阶阶段的笔记记录,具体记录顺序是:多线程、集合、网络编程、注解和反射、GUI(简单记录)。当这些记录完毕后会开始JavaWeb方面的记录。 文章目录JavaSE进阶(一)——多线程概述前言多线程概述进程线程线程使用线程创建Thread类Runnable接口线程等待实现Callable接口(了解即可)总结 多线程概述 多线程就是一心多用,我们在日常的时候可以同时处理很多事。一边吃饭、一边刷剧;一边做家务,一边唱歌。其实在计算机中

老程的小白博客空间 536

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

javase进阶 - 多线程

JavaSE进阶 - 多线程 1、基本概念 什么是进程? 进程是一个应用程序(1个进程是一个软件)。 什么是线程? 线程是一个进程中的执行场景/执行单元,一个进程可以启动多个线程。 对于Java程序来说,当在DOS命令窗口中输入: java HelloWorld 回车之后 会先启动JVM,而JVM就是一个进程,JVM在启动一个主线程调用main方法,同时在启动一个垃圾回收器线程负责看护,回收垃圾。一个是垃圾回收器线程、一个是执行main方法的主线程。 进程和线程之间是什么关系? 阿里巴巴:进程 马云:阿

Hello_super的博客 506

JavaSE进阶、多线程

/使用多线程//默认执行的线程为主线程如main方法//3、new一个新线程对象//多态//4、调用start方法,实际还是调用run方法t.start();i

飞翔的企鹅的博客 241

JavaSE进阶(集合、多线程、反射)

JavaSE进阶(集合、多线程、反射) 集合 说说常见的集合有哪些吧? 答:Map接口和Collection接口是所有集合框架的父接口: Collection接口的子接口包括:Set接口和List接口 Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等 Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等 List接口的实现类主要有:ArrayList、LinkedList、Stack

雍正写BUG 245

JavaSE进阶-多线程

多线程相关概念 【了解】 多线程的三种实现方式 【重点】 Thread类的常用方法 【重点】 多线程安全问题 【重点】...

aaa934946088的博客 939

JavaSE进阶:多线程(一)

JavaSE进阶:多线程(一):1.线程简介、2.线程实现(重点)

雙馬程序猿 449

JavaSE进阶06-多线程

a) 多线程的基本概念 b) 线程的创建和启动 c) 线程的生命周期 d) 线程的调度 e) 线程控制 f) 线程的同步 g) 守护线程 h) 定时器的使用 i) windows 的任务计划

cry30867的博客 333

JavaSE 进阶 - 第24章 多线程(1)

JavaSE 进阶 - 第24章 多线程(1)1、多线程概述2、实现线程的 2 种方式3、线程对象的生命周期4、关于线程java.lang.Thread的一些方法传送门 1、多线程概述 1.1、什么是进程?什么是线程? 进程是一个执行中的应用程序(1个进程是1个运行中的软件)。 线程是一个进程中的执行场景/执行单元。 一个进程可以启动多个线程。 1.2、对于java程序来说,当在DOS命令窗口中输入: java HelloWorld 回车之后: 会先启动JVM,而JVM就是一个进程:

佬涛的博客 615

JavaSE进阶之多线程-线程创建

Java多线程创建

m0_72975778的博客 264

Javase进阶1:多线程

目录 0.学习目标 1. 笔记 2. 练习 0.学习目标 1、整理多线程题目 (1)wait和sleep区别 (2)线程的状态有哪些 (3)在同步代码块或者同步方法中,什么情况下会释放锁 2、编写多线程代码 /** * 创建两个线程 * 创建一个初始 变量 值 包子状态为false * 实现一个线程吃包子,另外一个线程做包子 * 交替,进行10次 */ 3、编写泛型方法,实现两个数相加,限定参数只能是数字 1. 笔记 1、线程间通信 (1)创建线程因为操作系统进行...

weixin_43498449的博客 338

JavaSE进阶笔记-多线程01

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。 1.2并发和并行【理解】 并行:在同一时刻,有多个指令在多个CPU上同时执行。 并发:在同一时刻,有多个指令在单个CPU上交替执行。 1.3进程和线程【理解】 进程:是正在运行的程序 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位 动态性:进程的实质是程序的一次执行过程,进程是动态产生,动态

SUIT THUG!的博客 328
上一篇: javase进阶之IO
下一篇: javase之网络编程
continueLR
博客等级 码龄6年 9粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值