>  기사  >  Java  >  springboot에서 멀티스레드를 개발할 때 주의해야 할 점은 무엇입니까? (요약)

springboot에서 멀티스레드를 개발할 때 주의해야 할 점은 무엇입니까? (요약)

不言
不言원래의
2018-09-25 15:44:415083검색

이 기사에서는 springboot에서 멀티 스레드를 개발할 때 주의해야 할 사항에 대해 설명합니다. (요약) 도움이 필요한 친구들이 참고할 수 있을 만큼 참고할만한 가치가 있습니다.

springboot 기반의 멀티스레드 프로그램 개발 과정에서 springboot를 활용하기 위해서는 스프링 컨테이너 자체를 주입하여 관리해야 하기 때문입니다. 따라서 본 글에서는 두 가지를 결합하여 개발할 때 주의해야 할 사항을 기록하는 데 주로 사용된다.

첫 번째 단계는 관리를 위해 스레드 클래스의 인스턴스를 sping 컨테이너에 주입하는 것입니다

@Configuration
@SpringBootApplication
@Import({ThreadConfig.class})
public class ThreadApp implements CommandLineRunner
{
    public static void main(String[] args) throws Exception {

        ApplicationContext app = SpringApplication.run(ThreadApp .class, args);
        //这里主要保存上下文对象实例,需要加上。SpringBootUtils类网上很多,可以自己搜下
        SpringBootUtils.setApplicationContext(app);

    }

    //access command line arguments
    @Override
    public void run(String... args) throws Exception {
        //do something
    }
}

//ComponentScan注解会扫描com.demo.thead下,也就是多线程类所在的包下的文件
@Configuration
@ComponentScan(basePackages = { "com.demo.thread"})
public class ThreadConfig{

}

여기서 springboot @Import 주석을 사용하여 ThreadConfig에서 스캔한 패키지에 @와 같은 주석이 달린 예제를 주입합니다. Component 등을 컨테이너에 넣습니다.

그런 다음 스레드가 시작됩니다. 내 비즈니스 시나리오에는 두 가지 상황이 있습니다.

1 프로그램이 실행되면 자동으로 시작됩니다.

이것은 일반 실행 프로그램에 있습니다. 물론 메인 실행에서 직접 코드를 통해 스레드를 시작할 수도 있습니다. 하지만 springboot에서는 @PostConstruct 주석을 사용하여 Bean 컨테이너에 주입된 스레드 객체가 자동으로 시작되도록 할 수 있습니다

@Component
public class  demoThread extends Thread
{
    //注意这里,如果你没有实现把多线程类的实例注入到spring容器中,这里你是无法拿到其他自动装配的对象实例的的,这也是我们第一步的意义所在。
    @Autowired
    private XxxService xxxService;

    @PostConstruct
    public void start() {
        super.start();
    }

    public void run() {
        // Ok,在这里你就可以实现线程要实现的功能逻辑了,自然也可以直接使用装配好的sevice对象实例。
        
    }
}

2. 프로그램에서 스레드를 시작해야 할 때 시작합니다. 물론 이 경우 스레드 클래스 인스턴스를 sping 컨테이너에 삽입하는 첫 번째 단계도 거쳐야 합니다.

 private TaskThread thread;
    private ExecutorService taskPool= new ThreadPoolExecutor(
            5, 10, 1000,
            TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10),
            new ThreadPoolExecutor.CallerRunsPolicy());  


    @KafkaListener(topics = "xxTopic")
    public void receive(ConsumerRecord<Object, Object> consumerRecord) {
           JSONObject json =  JSON.parseObject(consumerRecord.value().toString());
           //通过SpringBootUtils获取线程类的实例
           thread = SpringBootUtils.getBean(TaskThread.class);
           //启动线程
           //new Thread(thread).start() ; 
           //向线程对象里传值
           thread.init(i);
           //放入线程池执行
           taskPool.execute(thread);

    }

//注意这里是否添加@Scope("prototype")注解
@Component
@Scope("prototype")
public class TaskThread  implements Runnable{
    
    protected int value=0;

    @Autowired
    private XxxService xxxService;
    
    //ThreadLocal  对象,单例模式下可以保证成员变量的线程安全和独立性。
    public ThreadLocalc0f559cc8d56b43654fcbe4aa9df7b4a valueLocal =  new ThreadLocal 46fc8f240055341038a5bc0c386009d9 () {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    protected static final Logger LOG = LoggerFactory.getLogger(GpsTaskThread.class);
    
    @Override
    public final void run() {
        try { 
            LOG.info(value+"");
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void init(int Value) {
        this.value=Value;
    }


}

여기에 필요합니다. spirngboot에 TaskThread 스레드 클래스가 필요한지 여부에 주의하세요. 다중 인스턴스 모드 또는 기본 싱글톤 모드로 설정하려면 @Scope("prototype") 주석을 추가하세요.

싱글톤 모드에서는 SpringBootUtils.getBean(TaskThread.class)이 매번 동일한 객체를 반환하지만 매번 새로운 객체를 생성할 필요는 없지만 멤버 변수의 스레드 안전성은 보장할 수 없습니다. 스레드 풀의 실행 스레드는 해당 값을 공유합니다. 멀티 인스턴스 모드에서는 매번 새로운 스레드 개체가 생성되므로 위의 문제는 존재하지 않습니다.

위의 샘플 코드이든 일반 웹 개발이든 상관없이 spirngboot는 기본적으로 싱글톤 모드로 설정되어 있으며 스레드에 안전하지 않으며 ThreadLocal 또는 기타 동기식 처리를 통해 수행되어야 합니다.

각 스레드가 서로 영향을 주지 않고 서로 다른 값을 처리해야 하는 현재 비즈니스 시나리오로 돌아가서 @Scope("prototype") 주석을 통해 TaskThread를 다중 인스턴스 모드로 설정합니다.

Summary

위의 예를 통해 springboot와 멀티스레딩의 조합이 비교적 간단하다는 것을 알 수 있습니다. 구성을 통해 스프링 컨테이너에서 스레드 클래스를 관리할 수 있을 뿐만 아니라 스프링 컨테이너에서 객체 인스턴스도 사용할 수 있습니다. 스레드에서. 동시에 우리는 사용 중 스레드 안전 문제와 내부 작동 메커니즘 문제에 의식적으로 주의를 기울여야 합니다. 물론 여기에서의 이해는 여전히 상대적으로 간단합니다. 잘못된 점이 있으면 지적하고 설명해주세요.

위 내용은 springboot에서 멀티스레드를 개발할 때 주의해야 할 점은 무엇입니까? (요약)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.