首页 > 其他分享 >多线程基础

多线程基础

时间:2023-01-30 15:55:19浏览次数:34  
标签:String Thread 基础 线程 new 多线程 守护 log

ThreadFactory线程工厂
生产线程的工厂,newThread是生产线程的方法,可以定义线程的基本特性。(比如优先级、是否守护线程)   join 调用join方法就会优先执行这个线程(thread1),等执行完毕后才会执行其他线程(thread执行完,再执行主线程)

public static void main(String[] args) throws InterruptedException {
        BaseThread baseThread = new BaseThread();
        Thread thread1 = new Thread(baseThread);

        thread1.start();
        //thread1执行完毕后才会执行主线程
        thread1.join();

        log.info("主线程第二个子线程开始执行------");
        Thread thread2 = new Thread(baseThread);
        thread2.start();
    }

 




锁定部分代码,确保数据准确。配合和synchronized使用,弥补synchronized的不足。
    //生成锁对象
    Lock lock = new ReentrantLock();

    @Override
    public void run() {
        //获取锁
        lock.lock();
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放锁
            lock.unlock();
        }
        System.out.println(Thread.currentThread().getName() + ": " + new Date());
    }

 

 

Redis设置分布式锁
因为分布式系统使用synchronized和lock只能锁住单台服务器,这样无法确保分布式下这段逻辑准确。
@Autowired
private StringRedisTemplate stringRedisTemplate;


boolean isAccess = false;
String invoiceKey = String.format(ApiRedisKey.AGENT_WITHDRAW_INVOICE, req.getBaseUserId());
try {
//setIfAbsent 不存在就新增,存在就不改变原有的值。存在返回false,不存在返回true.
    isAccess = stringRedisTemplate.opsForValue().setIfAbsent(invoiceKey, "1", 60, TimeUnit.SECONDS);
JlpayAssert.isTrue(isAccess, "正在处理,稍后再试");
//批处理ID(时间戳+用户ID)
String batchNo = System.currentTimeMillis() + String.format("%010d", req.getBaseUserId());
InvoiceVo invoiceVo = new InvoiceVo();
invoiceVo.setBatchNo(batchNo);
invoiceVo.setLicenseNo(getLicenseNo(req.getBaseUserId()));
HashMap<String, WithdrawChannelVo> channelMap = getChannelMap();
invoiceService.saveSubmitInvoice(req, channelMap, invoiceVo);
FixedThreadPoolUtil.INSTANCE.execute(() -> {
log.info("提现开票异步任务--开始");
ThreadContext.put("logid", ContextUtil.getThreadLogId());
//一般纳税人
List<WithdrawInvoice> withdrawInvoiceList = invoiceService.getWithdrawInvoiceList(batchNo, TaxType.GENERAL.code, "");
generalInvoice(batchNo, withdrawInvoiceList);
//小规模纳税人处理
HashMap<String, WithdrawChannelVo> smallScaleChannelMap = getSmallScaleChannel();
smallScaleInvoice(batchNo, smallScaleChannelMap);
log.info("提现开票异步任务--结束");
});
} finally {
if (isAccess) {
stringRedisTemplate.delete(invoiceKey);
}
}

 

  run和start的区别

 

线程优先级
线程的优先级由1 -- 10 ,最低是1最高是10,优先级越高越可优先获取cpu去执行任务,但不绝对。



守护线程:

如果 JVM 中没有一个正在运行的非守护线程,这个时候,JVM 会退出。换句话说,守护线程拥有自动结束自己生命周期的特性,而非守护线程不具备这个特点。

 

//创建一个线程

public class DaemonThread implements Runnable {
    @SneakyThrows
    @Override
    public void run() {

        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            log.info(Thread.currentThread().getName() + i);
        }
    }
}


//测试守护线程和非守护线程
public static void main(String[] args) throws InterruptedException {
        DaemonThread daemonThread = new DaemonThread();
        Thread thread = new Thread(daemonThread, "daemon thread jason");
        //true为守护线程:主线程结束,子线程也会结束
        //默认false非守护线程:主线程结束,子线程还会继续执行
        thread.setDaemon(true);
        thread.start();
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            log.info(Thread.currentThread().getName() + i);
        }
        log.info("主线程结束---------");
    }

 

主线程结束,守护线程就会结束,非守护线程依然会执行完毕。 

 

标签:String,Thread,基础,线程,new,多线程,守护,log
From: https://www.cnblogs.com/zhougongjin/p/17076248.html

相关文章