Java基础---反射、多线程

2023-10-26

十、反射机制

1.Java反射机制概述

1.1Java Reflection

●Reflection(反射)是被犯为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子到类的结构,所以,我们形象的称之为:反射

1.2Java反射机制提供的功能

在运行时判断任意一个对象所属的资T>在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法>在运行时获取泛型信息
在运行时调用任意一个对象的成员变量和方法>在运行时处理注解
生成动态代理

2.理解Class类并获取Class实例

哪些类型可以有class对象?
(1) class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
(2) interface:接口
(3)[]:数组
(4) enum:枚举
(5) annotation:注解@interface
(6) primitive type:基本数据类型
(7) void

3.类的加载与ClassLoader的理解

1.类的加载过程

当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化a

1 2 3
类的加载 类的链 按类的初始化
(Load) (Link) (Initialize)
将类的class文件读入内存,并为之创建一个java.lang.Class对象。此过程由类加载器完成 将类的二进制数据合并到JRE中 JVM负责对类进行初始化

加载: 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时
数据结构,然后生成一个代表这个类的ava.lang.ulas通N这个Class对象。这个加载的入口(即引用地址)。所有需要访问和使用类数据只能通过这个Class对象。这个加载的
过程需要类加载器参与。

链接: 将Java类的二进制代码合并到JVM的运行状态之中的过程。

验证:确保加载的类信息符合JVM规范,例如:以cafe开头,没有安全方面的问题

准备:正式为类变量( static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配。

解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。

初始化:
1.执行类构造器()方法的过程。类构造器()方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)。

2.当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。

3.虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步。

2.类加载器的作用:

类加载的作用: 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。

类缓存: 标准的JavaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过JVM垃圾回收机制可以回收这些Class对象。

3.ClassLoader

了解:ClassLoader
类加载器作用是用来把类(class)装载进内存的。

4.创建运行时类的对象

5.获取运行时类的完整结构

6.调用运行时类的指定结构

7.反射的应用:动态代理

●代理设计模式的原理:
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

之前为大家讲解过代理机制的操作,属于静态代理,特征是代理类和目标对象的类都是在编译期间确定下来,不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理。
最好可以通过一个代理类完成全部的代理功能。

/**
 *  静态代理举例
 *
 *  特点:代理类和被代理类在编译期间,就确定下来了。
 */

interface ClothFactory{

    void produceCloth();
}

class ProxyClothFactory implements ClothFactory{

    private  ClothFactory factory;//用被代理类对象进行实例化

    public ProxyClothFactory(ClothFactory factory){
        this.factory = factory;
    }


    @Override
    public void produceCloth() {
        System.out.println("代理工厂做一些准备工作");

        factory.produceCloth();

        System.out.println("代理工厂做一些后续的收尾工作");
    }
}

//被代理类
class NikeClothFactory implements ClothFactory{

    @Override
    public void produceCloth() {
        System.out.println("Nike工厂生产一批运动服");
    }
}
public class StaticProxyTest {

    public static void main(String[] args) {
        //创建被代理类对象
        NikeClothFactory nike = new NikeClothFactory();
        //创建代理类对象
        ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nike);

        proxyClothFactory.produceCloth();
    }

}

/**
 *  动态代理举例
 *
 */

interface Human{

    String getBelief();

    void eat(String food);

}

//被代理类
class SuperMan implements Human{

    @Override
    public String getBelief() {
        return "I believe I can fly";
    }

    @Override
    public void eat(String food) {
        System.out.println("我喜欢吃" + food);
    }
}

/*
    要想实现动态代理,需要解决的问题?
        门题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象。
        问题二:当通过代理类的对象调用方法时,如何动态的去调用被代理类中的同名方法。
 */

class ProxyFactory{
    //调用此方法返回一个代理类的对象,解决问题一
    public static Object getProxyInstance(Object obj){//obj:被代理类的对象

        MyInvocationHandler handler = new MyInvocationHandler();

        handler.bind(obj);

        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);
    }
}

class  MyInvocationHandler implements InvocationHandler{

    private Object obj;//赋值时需要使用被代理类对象赋值

    public void bind(Object obj){
        this.obj = obj;
    }

    //当我们通过代理类的对象调用方法a时就会自动的调用如下的方法:invoke()
    //将被代理类要执行的方法a的功能声明在invoke()中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //method:即为代理类的抽象方法,此方法也就作为了背代理类调用的方法
        //obj: 被代理类的对象
        Object returnValue = method.invoke(obj, args);
        //上述方法的返回值就作为当前类中的invoke()的返回值
        return returnValue;
    }
}
public class ProxyTEST {
    public static void main(String[] args) {
        SuperMan superMan = new SuperMan();
        //proxyInstance:代理类的对象
        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
        //当通过代理类对象调用方法时,会自动的调用被代理类中同名的方法
        String belief = proxyInstance.getBelief();
        System.out.println(belief);
        proxyInstance.eat("大猪蹄子");
    }
}

十一、多线程

1.基本概念:程序、进程、线程

程序(progran) 是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。

进程(process) 是程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程:有它自身的产生、存在和消亡的过程。——生命周期

如:运行中的QQ,运行中的MP3播放器
程序是静态的,进程是动态的
进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域

线程(thread) 进程可进一步细化为线程,是一个程序内部的一条执行路径。

若一个进程同一时间并行执行多个线程,就是支持多线程的
线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开销小
一个进程中的多个线程共享相同的内存单元/内存地址空间→它们从同一堆中分配对象,可以访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资源可能就会带来安全的隐患。

使用多线程的优点
背景:以单核CPU为例,只使用单个线程先后完成多个任务(调用多个方法),肯定比用多个线程来完成用的时间更短,为何仍需多线程呢?
多线程程序的优点:
1.提高应用程序的响应。对图形化界面更有意义,可增强用户体验。2.提高计算机系统CPU的利用率
3.改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改

2.线程的创建和使用

Thread类的有关方法:

ovoid start():启动线程,并执行对象的run()方法
run():线程在被调度时执行的操作
String getName():返回线程的名称
void setName(String name):设置该线程名称
static Thread currentThread():返回当前线程。在Thread子类中就是this,通常用于主线程和Runnable实现类
static void yield():线程让步
 暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程
 若队列中没有同优先级的线程,忽略此方法
join():当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到join()方法加入的join线程执行完为止
 低优先级的线程也可以获得执行
static void sleep(long millis):(指定时间:毫秒)
 令当前活动线程在指定时间段内放奋对CPU控制,使其他线程有机会被执行,时间到后重排队。
 抛出InterruptedException异常
stop():强制线程生命期结束,不推荐使用
boolean isAlive():返回boolean,判断线程是否还活着

线程的调度
调度策略:
1.时间片调度
2.抢占式:高优先级的线程抢占CPU

Java的调度方法
同优先级线程组成先进先出队列(先到先服务),使用时间片策略>对高优先级,使用优先调度的抢占式策略

线程的优先级
线程的优先级等级

MAX_PRIORITY: 10
MIN_PRIORITY:1
NORM_PRIORITY: 5

涉及的方法

getPriority():返回线程优先值工
setPriority(int newPriority):改变线程的优先级

说明

线程创建时继承父线程的优先级
低优先级只是获得调度的概率低,并非一定是在高优先级线程之后才被调用

3.线程的生命周期线程的同步

JDK中用Thredd.State类定义了线程的儿种状态
要想实现多线程,必须在主线程中创建新的线程对象。Java语言使用Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常要经历如下的五种状态:

新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源
运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能
阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU并临时中止自己的执行;进入阻塞状态
死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束

4.线程的同步

/**
 *  例子:创建三个窗口买票,总票数为100张 使用继承Thread类的方式
 *
 *  存在线程安全问题:待解决
 *
 *  1.问题:卖票过程中,出现了重票、错票 -->出现了线程安全问题
 *  2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,
 *    其他线程参与进来,也操作车票。
 *  3.如何解决:当一个线程在操作ticket的时候其他线程不能参与进来。
 *    直到线程a操作完ticket时,其他线程才可以操作ticket。这种情况
 *    即使线程a出现了阻塞,也不能被改变
 *  4,在Java中通过同步机制解决线程安全问题。
 *
 *  方式一:同步代码快
 *      synchronized(同步监视器){
 *          //需要被同步的代码
 *      }
 *   说明:操作共享数据的代码时需要被同步的代码
 *   共享数据:多个线程共同操作的变量
 *   同步监视器:俗称:锁。任何一个类的对象都可以充当锁。
 *                    要求:多个线程必须共用同一把锁
 *  方式额:同步方法
 *
 */
class Windows extends Thread{
    Object obj = new Object();
    private static int ticket = 100;

    @Override
    public void run() {
        while (true){
            synchronized(obj){
                if(ticket > 0){
                    System.out.println(getName() + ":买票,票号为" + ticket);
                    ticket--;
                }else {
                    break;
                }
            }

        }
    }
}

public class WindowsTest {
    public static void main(String[] args) {
        Windows w1 = new Windows();
        Windows w2 = new Windows();
        Windows w3 = new Windows();

        w1.setName("窗口一");
        w2.setName("窗口二");
        w3.setName("窗口三");

        w1.start();
        w2.start();
        w3.start();
    }
}
2.线程的死锁问题

死锁

不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续

解决方法

专门的算法、原则
尽量减少同步资源的定义
尽量避免嵌套同步

3.Lock(锁)

 从JDK5.0开始,Java提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当。
 java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。
 ReentrantLock类实现了Lock ,它拥有与synchronized 相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁、释放锁。

解决线程安全方式三:Lock锁

/**
 *  解决线程安全方式三:Lock锁   JDK5.0新增
 *
 *  1.面试题: synchronized 与Lock的异同?相同:二者都可以解决线程安全问题
 * 不同: synchronized机制在执行完相应的同步代码以后,自动的释放同步监视
 * Lock需要手动的启动同步(Lock()),同时结束同步也需要手动的实现(unlock())
 *
 *
 */

class Window implements Runnable{

    private int ticket = 100;
    //实例化一个Lock
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true){
            try {

                //2.调用锁定的方法lock()
                lock.lock();
                if(ticket > 0){

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ": 售票,票号为:" + ticket);
                    ticket--;
                }else{
                    break;
                }
            }finally {
                //3.调用解锁的方法unlock()
                lock.unlock();
            }

        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window w = new Window();
        Thread thread1 = new Thread(w);
        Thread thread2 = new Thread(w);
        Thread thread3 = new Thread(w);

        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

5.线程的通信

涉及到的三个方法:

  • wait():一旦执行此方法,当前线程就进入阻塞状态并释放同步监视器
  • notify():一旦执行此方法,就会先后被wait的线程,多个线程被wait,则唤醒优先级高的那个
  • notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。

说明:

  • 1.wait()、notify()、notifyAll()只能出现在同步代码块和同步方法中,lock中不行
  • 2.wait( )、notify()、notifyALL()三个方法的调用者必须是同步代码块或同步方法中的同步监视器
    否则,会出现ILLegaLMonitorStateException异常
  • 3.wait()、notify()、notifyALL()三个方法是定义在java.Lang.object类中。

面试题:sleep()和 wait()的异同?

  • 1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
  • 2.不同点:
    1)两个方法声明的位置不同: Thread类中声明sleep() , object类中声明wait()。
    2)调用的要求不同: sleep()可以在任何需要的场景下调用。wait()必须使用在同步代块或同步方法中调用。
    3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁
/**
 *  线程通讯的例子:
 *      使用两个线程交替打印1-100。线程1,线程2交替打印
 *
 *  涉及到的三个方法:
 *  wait():一旦执行此方法,当前线程就进入阻塞状态并释放同步监视器
 *  notify():一旦执行此方法,就会先后被wait的线程,多个线程被wait,则唤醒优先级高的那个
 *  notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。
 *
 *  说明:
 *  1.wait()、notify()、notifyAll()只能出现在同步代码块和同步方法中,lock中不行
 *  2.wait( )、notify()、notifyALL()三个方法的调用者必须是同步代码块或同步方法中的同步监视器
 *  否则,会出现ILLegaLMonitorStateException异常
 *  3.wait()、notify()、notifyALL()三个方法是定义在java.Lang.object类中。
 *
 *  面试题:sleep()和 wait()的异同?
 * 1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
 * 2.不同点:1)两个方法声明的位置不同: Thread类中声明sleep() , object类中声明wait()。
 *         2)调用的要求不同: sleep()可以在任何需要的场景下调用。wait()必须使用在同步代块或同步方法中调用。
 *         3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁
 */

class Number implements Runnable{

    private int number = 1;

    @Override
    public void run() {

        while(true){
            synchronized (this) {

                notify();

                if(number <= 100){
                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    number++;

                    try {
                        //使得调用如下wait()的线程进入阻塞状态
                        //会释放同步监视器
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else{
                    break;
                }
            }
        }

    }
}

public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }
}

6.JDK5.0新增线程创建方式

新增方式一:实现Callable接口

与使用Runnable相比,Callable功能更强大些相比run()方法,可以有返回值
方法可以抛出异常
支持泛型的返回值
需要借助FutureTask类,比如获取返回结果

新增方式二:使用线程池

背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具。
好处:
提高响应速度(减少了创建新线程的时间)
降低资源消耗(重复利用线程池中线程,不需要每次都创建)便于线程管理
 corePoolSize:核心池的大小
 maximumPoolSize:最大线程数
 keepAliveTime:线程没有任务时最多保持多长时间后会终止

线程池相关API
JDK 5.0起提供了线程池相关APl:ExecutorServiceExecutors
ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor

void execute(Runnable command):执行任务/命令,没有返回值,一般用来执行
Runnable
Future submit(Callable task):执行任务,有返回值,一般又来执行Callablq
void shutdown():关闭连接池

Executors: 工具类、线程池的工厂类,用于创建并返回不同类型的线程池

Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池
Executors.newFixedThreadPool(n);创建一个可重用固定线程数的线程池
Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池
Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

创建线程的方式三:实现Callable接口

/**
 *  创建线程的方式三:实现Callable接口。 JDK 5.0
 *
 *
 *
 *
 */

    //1.创建一个实现Callable的实现类
class numberThread implements Callable{
    //2.实现call方法,将此线程需要执行的操作声明在call()中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if(i % 2 == 0){
                System.out.println(i);
                sum = sum + i;
            }
        }
        return sum;
    }
}

public class ThreadNew {
    public static void main(String[] args) {
        //3.创建callable实现类的对象
        numberThread numberThread = new numberThread();
        //4.将此Callable接口实现类的对象作为参数传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask futureTask = new FutureTask(numberThread);
        //5将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start();
        new Thread(futureTask).start();

        try {
            //6.获取Callable中call方法的返回值
            //get()返回值即为FutureTask构造器参数Callable实现类重写的caLL()的返回值。
            Object o = futureTask.get();
            Integer integer = (Integer) o;
            System.out.println(o);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

创建线程的方式四:线程池

/**
 *  创建线程的方式四:
 *  好处:
 *  1.提高响应速度(减少了创建新线程的时间)
 *  2.降低资源消耗(重复利用线程池中线程,不需要每次都创建>)3.便于线程管理
 *      corePoolsize:核心池的大小
 *      maximumPoolsize:最大线程数
 *      keepAliveTime:线程没有任务时最多保持多长时间后会终止
 *
 */

class NumberThread5 implements Runnable{

    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {

        //1.提供指定数量的线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;

            //设置线程池的属性
//      service1.setCorePoolSize(15);
//      service1.setKeepAliveTime();
        
        //2,执行指定线程的操作。需要实现提供Runnable接口或者Callable接口的实现类对象
        service.execute(new NumberThread5());//适合用于Runnable
//      executorService.submit(Callable callable)//适合用于Callable
        //3.关闭线程池
        service.shutdown();
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java基础---反射、多线程 的相关文章

  • 两个或多个 Android 设备之间的 WiFi 聊天

    我想开发一个聊天应用程序 使用 wifi 网络在两个或多个 Android 设备之间聊天 该应用程序应该能够相互发送或接收字符串 我有在pc和android之间使用蓝牙网络的经验 任何人都可以给我任何建议或正确的方向 提前致谢 您可以在两个
  • 在 Java 中显式调用默认方法

    Java 8 引入默认方法 http cr openjdk java net dlsmith jsr335 jsr335 0 6 2 H html提供扩展接口的能力 而无需修改现有的实现 我想知道当该方法已被覆盖或由于不同接口中的默认实现冲
  • 使用 C++ 中的 java 套接字接收浮点数

    我需要使用套接字从 C 客户端到 java 服务器接收包含浮点数的数组或类 但 InputStreamReader 没有得到正确的结果 任何原因 任何有关更简单方法的建议将不胜感激 谢谢 Java服务器代码 public static vo
  • Google 云端点(应用程序引擎)+ oauth2 与 android 集成

    我正在尝试将谷歌应用程序引擎云端点 API 与 android 集成 我已经按照此链接进行了相同的操作 无法使用我的服务对象连接到我的谷歌端点 https stackoverflow com questions 29544723 unabl
  • Java流合并或减少重复对象

    我需要通过将所有重复条目合并到一个对象中来从可以具有重复项的列表中生成一个唯一的朋友列表 Example 从不同的社交源中获取好友并放入 1 个大列表中1 朋友 姓名 约翰尼 德普 出生日期 1970 11 10 来源 FB fbAttri
  • 停止或终止 JDBC 中长时间运行的查询

    有什么方法可以停止或终止 JDBC 中长时间运行的 Oracle 查询吗 通常最终会重新启动应用程序服务器以使 jdbc 与 Oracle DB 断开连接 寻找类似于 SQL Plus 的功能 Kill session在 Java 或 JD
  • 如何在 Spring 加载应用程序上下文后立即执行作业?

    我想在加载 Spring 上下文后运行一些作业 但我不知道该怎么做 你知道该怎么做吗 另一种可能性是注册应用程序上下文事件的侦听器 基本上与skaffman的解决方案相同 只需实现 org springframework context A
  • 如何在 Cucumber-JVM 中并行运行场景? [复制]

    这个问题在这里已经有答案了 我有一组为 Cucumber JVM 编写的验收测试 为了减少反馈时间 我想并行运行 功能的 场景 我该如何以最简单 最方便的方式做到这一点 我希望能够在 Java 代码中表达这一点 作为常规的 JUnit 测试
  • 是否可以在两个 Android 设备之间直接将数据传输给同一网络中的其他用户?

    假设我有两个 Android 移动设备 连接到同一个无线网络 并且该网络没有外部 互联网访问权限 在没有第三方软件的情况下 是否可以在不知道对方ip 不创建热点的情况下通过wifi传输数据 就像我们在 Windows 上所做的那样 如果 2
  • 按日期比较对象(实现 Comparator)

    我有一个 java People 对象 public class People String lastname String firstname String gender String datebirth String fcolor pu
  • 使用 nextFloat() 线程“main”中出现 java.util.InputMismatchException 异常

    所以我正在编写一个小程序来计算学生最好成绩的平均值 当我运行它时 我在线程 main java util InputMismatchException中收到此错误异常 我看到一篇文章说要使用 nextLine 然后使用 parseInt 在
  • 为什么 Android 中的 Locale.getDefault().getLanguage() 返回显示名称而不是语言代码?

    根据 Java 参考资料 Locale getLanguage 应该返回该语言的 2 个字母的小写 ISO 代码 例如en 尽管getDisplayLanguage 是获取可读名称的方法 例如English 那么Android中怎么会出现下
  • Spring @Transactional 和 Hibernate @LockMode 注释如何关联

    我想知道事务和锁之间的关系 更具体地说 Spring 的情况如何 Transactional与Hibernate的LockMode有关 https docs jboss org hibernate orm 4 0 devguide en U
  • 多次或单次 Try Catch [重复]

    这个问题在这里已经有答案了 我正在清理一些代码 但我不确定哪条路线更好 目前 我的大部分方法都有一个 try catch 块 它在最后处理一些单独的异常 但我认为有更多的 try catch 块对于维护来说会更好 然而 在分解代码时 我发现
  • Minecraft Forge 1.8 - 加载块纹理

    我刚刚开始学习 Java 同时修改 Minecraft 我看过有关使用 Minecraft Forge API 将块添加到游戏中的教程 但我遇到了问题 不再有 setBlockTextureName 方法 所以我不知道该怎么办 我在游戏中添
  • 如何根据 1 小时间隔获取时间段

    我想将时间段存储在数组列表中 我有开始时间和结束时间 根据开始时间 它应该创建时间段 例如 如果开始时间是 09 00AM 结束时间是 21 00PM 那么它应该添加到 arraylist 中 如下所示 上午 09 00 10 00 AM
  • 定制/扩展Spring对shiro的@Async支持

    我正在使用Spring的 EnableAsync异步执行方法的功能 为了安全起见 我使用 Apache Shiro 在异步执行的代码中 我需要访问附加到触发异步调用的线程的 Shiro 主题 Shiro 支持通过将主题与主题相关联来在不同线
  • Java EE 身份验证:如何捕获登录事件?

    给定为 Java Web 应用程序定义的 FORM 类型的身份验证机制 如何捕获已执行登录在重定向到请求的资源之前发生事件 是否有任何类型的侦听器可以让我在用户登录时执行我的代码 我觉得定义过滤器不是最好的解决方案 因为过滤器链接到资源 即
  • javax.mail.MessagingException:无法连接到 SMTP 主机:<主机名> 端口:25 响应:554

    我正在尝试使用 java mail api 发送邮件 我的 smtp 服务器是 ibm 服务器 我面临这个异常 javax mail MessagingException Could not connect to SMTP host
  • For 循环有效,但 For Each 无效。为什么?

    在包含 forEach 循环的行上抛出了越界异常 但据我所知 这段代码没有任何问题 for 循环从 char 数组的元素 0 开始并循环直到到达最后一个元素 但是当我使用更长的 for 循环尝试此代码时 即 for int i 0 i lt

随机推荐

  • vue.js --父子组件通信

    目录 父子组件通信 父组件向子组件通信 子组件通过props接收 子组件向父组件通信 emit自定义事件 v model改造 emit传递父组件数据 emit传递单个父组件数据 emit传递多个父组件数据 总结 父子组件通信 父子组件通信
  • 线程的状态

    线程共有六种状态 初始状态 实现Runnable接口和继承Thread可以得到一个线程类 new一个实例出来 线程就进入了初始状态 2 1 就绪状态 就绪状态只是说你资格运行 调度程序没有挑选到你 你就永远是就绪状态 调用线程的start
  • mybatis泛型DAO接口

    本文将记录mybatis整合spring的泛型DAO接口 通过BasicDAOImpl实现类提供CRUD功能 其他DAO只需要继承和扩展BasicDAOImpl BasicDao接口定义 public interface BasicDAO
  • win10系统下将DMG转为ISO镜像——(虚拟机黑苹果操作)

    1 下载镜像 http www msdn3 com 6 20190826 这个网站超级好用 2 下载后为dmg文件 如果可以直接下载iso文件的可以跳过转换步骤 3 dmg文件转iso文件 1 下载DMG2IMG 32位 64位版Windo
  • loadrunner接口压测脚本编写模板

    接口报文 Action web reg save param return code LB res code RB Search Body Ord 1 LAST lr start transaction httpRequest web ad
  • jdbc连接数据库mysql的问题_JDBC连接Mysql数据库出现的问题汇总

    MySQL 前言 最近安装了一个 mysql 8 0 版本的数据库 在程序中连接的时候可谓是状况不断 之前也会遇到一些问题 这里就对使用 JDBC 连接mysql 会出现的问题做一个汇总 在此之前说明一下环境 开发工具 IDEA mysql
  • Selenium自动化测试 —— 通过cookie绕过验证码的操作

    验证码的处理 对于web应用 很多地方比如登录 发帖都需要输入验证码 类型也多种多样 登录 核心操作过程中 系统会产生随机的验证码图片 进行验证才能进行后续操作 解决验证码的方法如下 1 开发做个万能验证码 推荐 2 测试环境关闭验证码功能
  • Easy Code插件使用(附Spring Data JPA生成模板)

    文章目录 一 概述 二 安装 1 安装插件 2 连接数据库 三 生成代码 四 配置EasyCode 五 Spring Data JPA模板 1 controller类 2 service接口 3 serviceImpl实现类 4 dao接口
  • Python之体育竞技分析

    来源 Python语言程序设计 嵩天 一 问题描述 需求 高手过招 胜负只在毫厘 如何科学地分析体育竞技比赛 输入 球员的水平 输出 预测比赛成绩 二 具体分析 三 代码实现 from random import random 生成随机数
  • uniapp picker实现:市区镇村4级懒加载

    使用这种方法的原因 市区镇村4级数据太大 后台接口响应时间太长 方法实现 样式 view
  • 深度学习各方向开源数据集分类汇总

    转载自 深度学习各方向开源数据集分类汇总 持续更新中 哔哩哔哩 目录 1 小目标检测 2 目标检测 3 人体姿态估计 4 图像分割 语义分割 5 工业检测 6 人脸识别 7 自动驾驶 8 目标跟踪 9 动作识别 10 图像分类 11 图像识
  • 基于Matlab的数字图像水印技术

    基于Matlab 的数字图像水印技术 课题介绍 数字水印技术涉及到许多图像处理算法以及数学计算工具等 如果用普通编程工具实现上述算法 需要要花费大量的时间 MathWorks公司推出的一种简单 高效 功能极强的高级语言 MATLAB语言 它
  • 局部最小值问题

    问题 一个数组 相邻不等 返回任意一个局部最小值 重点是 相邻不等 否则无法用此方法 分析 所谓局部最小值 即左右相邻的数都比他大 当此数为第一个时 只需要右边的比他大即可 最右同理 代码 生成随机数组 相邻不等 void Random a
  • B站疯传!堪称最强!java超级面试资料

    我没有知名企业的工作经历 也没有多么耀目的成就 为什么他们会对我有那么深的印象呢 其实 在我看来 面试都是有迹可循的 也就是说 完全可以用很短的时间准备 却给面试官留下很深的印象 一 好的自我介绍决定了面试的80 不管你相不相信 你适不适合
  • DataX理论知识:简介-框架设计-数据抽取策略

    文章目录 一 简介 二 框架设计 三 数据抽取策略 一 简介 DataX 是一个 异构数据源 离线同步工具 可实现 各种 异构数据源 之间 稳定高效的数据同步功能 设计理念 从 蜘蛛网 到 星型链路 DataX充当一个中转站的角色 二 框架
  • 数据分析——数据特征描述、画箱线图、分组直方图

    数据特征描述 import pandas as pd catering sale r H school 数据挖掘 实验 实验二 catering sale xls data pd read excel catering sale index
  • 如何对SQL Server中的tempdb“减肥”

    SQL Server会自动创建一个名为tempdb的数据库作为工作空间使
  • checkstyle:off 使用注释暂时禁用checkstyle检查

    背景 本文介绍在Gradle中 如何跳过checkstyle对指定的文件 或者指定的代码块 的检查 步骤 1 在checkstyle xml的
  • Typescript常见表达式

    Typescript常见表达式 一 析构表达式 destructuring 1 数组析构表达式 用中括号括起来 var array1 1 2 3 4 function doSomething number1 number2 others c
  • Java基础---反射、多线程

    十 反射机制 1 Java反射机制概述 1 1Java Reflection Reflection 反射 是被犯为动态语言的关键 反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息 并能直接操作任意对象的内部属性