多线程基础(实际开发实例)

线程:
多线程的好处: 多线程解决了在一个进程中同时可以执行多个任务代码的问题。
自定义线程的创建方式:

    方式一:继承Thread.
        1. 自定义一个类继承Thread类。
        2. 重写Thread的run方法,把自定义线程的任务代码定义在run方法上。
        3. 创建Thread子类的对象,并且调用start方法启动一个线程。
    方式二: 实现Runnable接口。
        1. 自定义一个类实现Runnable接口。
        2. 实现Runnable接口中的run方法,把自定义线程的任务代码定义在run方法上。
        3. 创建Runable实现类 的对象。
        4. 创建Thread对象,并且把Runnable实现类的对象作为参数传递。
        5. 调用Thread对象的start方法开启线程。
        
线程安全 问题的解决方案:

线程安全问题出现 的根本原因:
    1. 必须要存在两个或者两个以上的线程共享着一个资源。
    2. 操作共享资源的代码必须有两句或者两句以上。
解决方案:
    1. 同步代码块
        
        synchronized(锁){
            需要被同步的代码
        }
 
    2. 同步函数。
        
        修饰符 synchronized 返回值类型   函数名(形参列表..){
        
        }
    注意:
        1. 同步代码块的锁可以是任意的对象。 同步函数的锁是固定 的,非静态函数的锁对象是this对象。 静态函数的锁对象是class对象。
        2. 锁对象必须是多线程共享的对象,否则锁不住。
        3. 在同步代码块或者是同步函数中调用sleep方法是不会释放锁对象的,如果是调用了wait方法是会释放锁对象的。

  以方式二: 实现Runnable接口的demo调用多线程发送短信

      // 1. 自定义一个类SendMessageThreadForRegistRedpacket 实现Runnable接口。   

@Component("sendMessageThreadForRegistRedpacket")
@Scope("prototype")
public class SendMessageThreadForRegistRedpacket implements Runnable {

   //2. 实现Runnable接口中的run方法,把自定义线程的任务代码定义在run方法上。
@Override
public void run() {
System.out.println("开始执行多线程程序-------");
String message = "【CSDN】 【" + redpacketDetail.getRedpacketamount() + "】元,请尽快查看";
System.out.println("短信内容message:--------" + message);
SmsChannel effectiveChannel = smsChannelService.getEffectiveChannel(r.getBaseid(), 6, null);
if (effectiveChannel != null) {
String resultMsg = SMSSend.sendMessge(effectiveChannel, mobile, message);
if (!"短信发送异常".equals(resultMsg)) {
     smsRecordService.insertsmsRecord(effectiveChannel, mobile, message, resultMsg);
    if (resultMsg == "") {
        //已经发短信:0未发  1已发
        r.setHavebeentexting(Redpacket_Constant.HAVEBEENTEXTING_SENDED);
        r.setSendtime(new Date());
        redpacketSmsRemindService.updateById(r);
}

}else{

log.info("没有一个匹配到有效的短信通道");

}

}

@Controller
@RequestMapping("/admin/registRedpacketRules")
public class RegistRedpacketRulesController extends BaseCRUDController<RegistRedpacketRules> {
@ResponseBody
@RequestMapping(value = "/aa", method = {RequestMethod.POST})
public synchronized Map<String, Object> abc(RegistRedpacketRules registRedpacketRules) {
    Map<String, Object> map = new HashMap<>();
try {
System.out.println("begin new Thread Send Message");
      //3. 创建Runable实现类 的对象。
SendMessageThreadForRegistRedpacket sendMessageThreadForRegistRedpacket = ApplicationContextProvider.getBean("sendMessageThreadForRegistRedpacket", SendMessageThreadForRegistRedpacket.class);
    // 4. 创建Thread对象,并且把Runnable实现类的对象作为参数传递。

     //5. 调用Thread对象的start方法开启线程。
new Thread(sendMessageThreadForRegistRedpacket).start();

System.out.println("end new Thread Send Message");
        }
    }

} catch (Exception e) {
    e.printStackTrace();
    map.put(Result_Constant.MSG, "保存失败!<br />原因:" + e.getMessage());
}
return map;

}

//获取spring中的bean  此类在创建多线程时会用到
@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private static ApplicationContext context;

    private ApplicationContextProvider(){}

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public  static <T> T getBean(String name,Class<T> aClass){
        return context.getBean(name,aClass);
    }


}

猜你喜欢

转载自blog.csdn.net/orecle_littleboy/article/details/79413744