java多少线程操作共享数据线程安全问题加锁

发布时间:2024年01月17日

1、有问题的写法
AdminController文件

package com.controller;

import com.myThread.AdminThread;
import com.myThread.MyCallable;
import com.myThread.MyRunnable;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@RestController
@CrossOrigin
@RequestMapping("/admin")
public class AdminController{
    public static int count = 10;
    @GetMapping("/{id}")
    public long findById(@PathVariable Long id) throws InterruptedException {
        AdminThread t1 = new AdminThread();
        AdminThread t2 = new AdminThread();
        t1.start();
        t2.start();
        return id;
    }
}

AdminThread文件

package com.myThread;

import com.controller.AdminController;

public class AdminThread extends Thread{
    @Override
    public void run() {
        while (true){
            if(AdminController.count == 0){
                break;
            }
            AdminController.count--;
            System.out.print(getName()+"线程"+AdminController.count+"\n");
        }
    }
}

执行结果,可以看到重复执行,不安全
在这里插入图片描述

解决方法加锁
AdminController文件

package com.controller;

import com.myThread.AdminThread;
import com.myThread.MyCallable;
import com.myThread.MyRunnable;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@RestController
@CrossOrigin
@RequestMapping("/admin")
public class AdminController{
    //数量
    public static int count = 10;
    //锁对象
    public static final Object lock = new Object();
    public static boolean flag = false;

    @GetMapping("/{id}")
    public long findById(@PathVariable Long id) throws InterruptedException {
        AdminThread t1 = new AdminThread();
        AdminThread t2 = new AdminThread();
        t1.start();
        t2.start();
        return id;
    }
}

AdminThread文件

package com.myThread;

import com.controller.AdminController;

public class AdminThread extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized(AdminController.lock){
                if(AdminController.count == 0){
                    break;
                }else{
                    if(!AdminController.flag){
                        //操作
                        AdminController.count--;
                        System.out.print(getName()+"线程"+AdminController.count+"\n");
                        //释放
                        AdminController.lock.notifyAll();
                    }else{
                        //一直循环监听
                        try {
                            AdminController.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }

        }
    }
}

AdminThread上面这个!会有空执行(虽然没有错,但多跑了一点点),应该下面这样

package com.myThread;

import com.controller.AdminController;

public class AdminThread extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized(AdminController.lock){
                if(AdminController.count == 0){
                    break;
                }else{
                    //操作
                    AdminController.count--;
                    System.out.print(getName()+"线程"+AdminController.count+"\n");
                    //释放
                    AdminController.lock.notifyAll();
                }

            }

        }
    }
}

文章来源:https://blog.csdn.net/qq_34631220/article/details/135661449
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。