假设这情况情况, 同一台服务器上有个服务有两个进程(一般用作负载均衡, 以及在更新时切换使用). 有个定时任务, 但只需要其中之一执行就可以了.

添加一个注解类

import org.springframework.stereotype.Component;

import java.lang.annotation.*;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface FileLock {

}

添加一个AOP类

import com.google.common.hash.Hashing;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

@Aspect
@Component
public class FileLockAspect {

    private static final Logger log = LoggerFactory.getLogger(FileLockAspect.class);

    @Pointcut("@annotation(你的包名.FileLock)")
    public void lockAspect() {
        // aspect point
    }

    @Around("lockAspect()")
    public void doBefore(ProceedingJoinPoint jp) throws Throwable {
        final String key = jp.toLongString();
        final String hashCode = Hashing.sipHash24().hashBytes(key.getBytes()).toString();
        final File lockFile = new File("/tmp/" + hashCode + ".flock");

        if (!lockFile.exists()) {
            final boolean ok = lockFile.createNewFile();
            if (!ok) {
                log.error("can not create file {}. ", lockFile.getName());
                System.exit(-1);
            }
        }

        final RandomAccessFile randomAccessFile = new RandomAccessFile(lockFile, "rw");
        final FileChannel fileChannel = randomAccessFile.getChannel();
        FileLock fileLock = null;
        try {
            fileLock = fileChannel.tryLock();
            if (fileLock == null || !fileLock.isValid()) {
                log.info("other instance running....");
                return;
            }
            jp.proceed();
        } finally {
            if (fileLock != null && fileLock.isValid()) {
                log.info("release lock...{}", lockFile.getName());
                fileLock.release();
            }
            fileChannel.close();
        }
    }
}

你的任务类

    @FileLock
    @Scheduled(cron = "0 */3 * * * *")
    public void check() {
        ....
    }

pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>