实际开发中须要考虑线程安全的场景很常见,日常咱们能够用定时任务线程池模拟并发安全
线程安全是指在不少请求同时执行时,线程操做的类的数据不会出现错误多线程
好比下面这个类并发
public class test { private int a; private int b; public void operate(){ a = a - 1; b = b + 1; System.out.println("当前运行线程:"+Thread.currentThread().getName()+",a与b相加的值若 线程安全则结果一直为初始值"+(a+b)); } public test(int a,int b){//构造方法 this.a =a; this.b = b; } }
这个类建立的对象有两个值(a,b) 里面有一个方法 operate 假设如今有请求调用了这个operate方法若是线程安全的话 那么打印出来的就一直是构造时传入a,b值相加,若线程不安全就不必定了(固然这个方法在实际中是不会出现)ide
如今来模拟不少个请求来调用这个方法this
我首先想到的定时任务线程池来模拟线程
public class ServiceTest { public static void main(String[] args) { // TODO Auto-generated method stub test t = new test(100,200); ScheduledExecutorService service = Executors.newScheduledThreadPool(3); service.scheduleAtFixedRate(new MyThread(t), 1, 1,TimeUnit.SECONDS); ScheduledExecutorService service1 = Executors.newScheduledThreadPool(3); service1.scheduleAtFixedRate(new MyThread(t), 1, 2,TimeUnit.SECONDS); ScheduledExecutorService service2 = Executors.newScheduledThreadPool(3); service2.scheduleAtFixedRate(new MyThread(t), 1, 3,TimeUnit.SECONDS); ScheduledExecutorService service3 = Executors.newScheduledThreadPool(3); service3.scheduleAtFixedRate(new MyThread(t), 1, 4,TimeUnit.SECONDS); } } class MyThread implements Runnable{ private test t; public MyThread(test t){ this.t = t; } @Override public void run() { // TODO Auto-generated method stub t.operate(); } }
这里开了四个 定时任务(ScheduledExecutorService )code
第一个每隔1秒,第二个每隔2秒,第三个每隔3秒,第四个没隔4秒执行任务对象
所执行的任务就是 test类里面的operate方法开发
这里四个定时任务处理的都是同一个对象 test t = new test(100,200);get
多个任务同时处理一个对象才有可能出现并发问题
最开始operate方法没加synchronized ,执行一段时间后结果是这样的
结果中出现了301说明operate方法在多线程并发的状况下是不安全的
给方法加上synchronized 关键字 执行一段时间后结果任然是300这时代码是线程安全的