Web项目中简单的多线程使用

**

Java多个线程同时访问操作单例对象,需不需要加锁的问题

**
(1)多个线程处理单例对象的共有属性需加锁
ps:多个线程同时访问同一个方法,该方法操作了单例对象中共有(全局)的属性,则需要加锁。
(2)多个线程访问单例对象的同一方法,但该方法不处理共有属性则不需要加锁
(3)多个线程访问单例对象的static属性、方法需要加锁

结论:
操作共有属性,静态方法属性,加锁;只是调用方法,没有操作共有属性,不加锁。
方法中定义的局部变量在多线程下不会带来线程安全的问题。
**

线程的循环、休眠和停止

**
public void testCron1() throws Exception {
DateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
log.info(sdf.format(new Date())+"*****每1秒执行一次");
Thread thread = Thread.currentThread();
while (
!thread.isInterrupted()
) {
log.info(sdf.format(new Date())+“线程循环”);
long now = (new Date()).getTime();
if((now%3 == 0)){
log.info(now+“线程停止”);
thread.interrupt();
}else if ((now%2 == 0)) {
log.info(now+“进入休眠状态”);
thread.sleep(10000);
}
}
}
注意:进入休眠状态再度循环的是while里的代码
**

Spring注入与多线程

**
Spring不能在线程中注入,在线程中使用@Resource或者@Autowired注入全部为NULL
解决:
1、将需要注入的Bean在线程创建前就注入或者作为线程的构造函数参数传入

多线程定时器:

    @Autowired
	private HsSchedulerMapper hsSchedulerMapper;
	@Autowired
	@Qualifier("ApplyAccount")private HsSchedule ApplyAccount;
	private ConfigResources cfg = new ConfigResources(HsjkClient.class.getResourceAsStream("/HS.properties"));
	private HttpClient client = new HttpClient();

	   //线程1
	   @Scheduled(cron="0/5 * * * * ? ")   //每4秒执行一次 
	    public void testCron6() {
	       DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
	       log.info(sdf.format(new Date())+"*********线程1执行一次");
		   ApplyAccount.scheduleTaskFirst(cfg, client, hsSchedulerMapper);
	    }
	   
	   //线程2
	   @Scheduled(cron="0/5 * * * * ? ")   //每4秒执行一次 
	    public void testCron7() {
		   DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
		   log.info(sdf.format(new Date())+"*********线程2执行一次");
		   ApplyAccount.scheduleTaskSecond(cfg, client, hsSchedulerMapper);
	    }

作为构造函数参数传入:

class Test{

    //这两个为线程所需要的Bean
    @Resource
    TestDao1 testDao1;

    @Resource
    TestDao2 testDao2;

    public void serviceExecute(){
        //在这里开启线程,执行操作
        ThreadExample te = new ThreadExample(TestDao1 testDao1,TestDao2 testDao2);
        te.start();
    }
    
    //内部类
    private class ThreadExample extends Thread{
		private TestDao1 testDao1 = null;
		private TestDao2 testDao2 = null;

        public ThreadExample(TestDao1 testDao1,TestDao2 testDao2){
            //也可以在构造函数中传入参数
            this.testDao1 = testDao1;
            this.testDao2 = testDao2;
        }
        public void run(){
            //这里为线程的操作
            //就可以使用注入之后Bean了
            testDao1.xxx();
            testDao2.xxx();
        }
    }
}

2、使用ApplicationContext.getBean方法来静态的获取Bean
(摘抄自https://www.cnblogs.com/vinozly/p/5223147.html)
(1)定义工具类

@Component 
public class SpringApplicationContextHolder implements ApplicationContextAware {  
  
    private static ApplicationContext context;  
  
    @Override  
    public void setApplicationContext(ApplicationContext context) throws BeansException {  
        SpringApplicationContextHolder.context = context;  
    }  
  
    public static Object getSpringBean(String beanName) {  
        notEmpty(beanName, "bean name is required");  
        return context==null?null:context.getBean(beanName);  
    }  
  
    public static String[] getBeanDefinitionNames() {  
        return context.getBeanDefinitionNames();  
    }

(2)线程中获取bean

UserRepo user = (UserRepo) SpringApplicationContextHolder.getSpringBean("userRepo"); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值