多线程操作方式

public class UserService {

    /**
     * 堆内存   共享的,都会从这个区间来进行获取得到对应的对象
     * 每个都会有个线程栈空间而已,但是会涉及到共享资源
     * 那么堆共享资源的操作,应该涉及到互斥
     * 这个需要来对其实现注意!
     * 其实和lock锁原理一致;
     */

    /**
     * 方法区
     */

    static int i = 10;

    public void show (){
        synchronized (this){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i--;
        }
    }
}

对应的操作代码:

public class CountdownLatchDemo1 {
    public static void main(String[] args) {
        UserService userService = new UserService();
        final CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                latch.countDown();
                userService.show();
                System.out.println("对应的值是:"+UserService.i);
            }).start();
        }
        try {
            latch.await();
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

画个图来进行对应的表示方式:

多个线程会去访问共享资源,但是共享如果没有被保护好,那么所有的都可以来进行对应的操作。

但是多个线程在使用同一个对象来调用方法的时候,每个线程都会另外起一个方法栈来调用方法,所以每个栈空间的会去访问到方法区或者是堆内存中的共享资源。

那么如果没有保护好,就会导致线程不安全的情况。所以考虑到这一点应该考虑到对应的解决方式:

@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {

    private static final Lock LOCK = new ReentrantLock();
    
    private static final Map<String,Object> MAP = new ConcurrentHashMap<>(255);
    
    private final UserMapper userMapper;

    /**
     * 不存在线程共享的问题,所以可以安全的来进行使用
     * @return
     */
    // 一定要注意使用@Transactional注解的使用方式,会导致注解失效
    @Override
    public List<User> queryUserByCondition() {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andIdIn(Arrays.asList(1,2,3,4));
        List<User> users = userMapper.selectByExample(userExample);
        return users;
    }

    // 如果多个线程中需要使用到共享资源,那么应该使用并发操作的变量来进行操作
    public List<User> update(Integer id) {
        Object constan_key = MAP.get("CONSTAN_KEY");
        if (Objects.nonNull(constan_key)){
            // doSomething.........
        }else {
            MAP.put("CONSTAN_KEY","helloworld");
        }
        // doOther.............
        return null;
    }
}
posted @ 2022-01-25 17:13  写的代码很烂  阅读(37)  评论(0编辑  收藏  举报