一,环境
idea
二.什么是线程安全问题,为什么会有线程安全问题
线程安全问题产生于多个线程同时访问共享资源(通常查询不会产生)
三.举例
假如我现在想讲一个数循化加一,最终增加到1000.但是需要用5个线程来加
class Count implements Runnable{ private int count=1; public void run() { while (count<=1000){ count=count+1; System.out.println(Thread.currentThread().getName()+",count:"+count); } } } public class ThreadTest { public static void main(String[] args) { Count count=new Count(); Thread t1=new Thread(count,"线程一"); Thread t2=new Thread(count,"线程二"); Thread t3=new Thread(count,"线程三"); Thread t4=new Thread(count,"线程四"); Thread t5=new Thread(count,"线程五"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }
结果:
代码显示:最多会增加到1000循环就会结束那么为什么会出现1001呢!!
由于现在是多线程增加,有可能当count增加到999的时候同时又两个线程都进入了while循环里,然后就连续增加了两次
那么怎么解决呢!!!
四.使用锁来解决
4.1同步代码块
class Count implements Runnable{ private volatile int count=1; private static Object oj = new Object(); public void run() { while (count<=1000){ synchronized (oj) {//oj就是锁对象可以为任意对象也可为this if(count<=1000) { count = count + 1; System.out.println(Thread.currentThread().getName() + ",count:" + count); } } } } } public class ThreadTest { public static void main(String[] args) { Count count=new Count(); Thread t1=new Thread(count,"线程一"); Thread t2=new Thread(count,"线程二"); Thread t3=new Thread(count,"线程三"); Thread t4=new Thread(count,"线程四"); Thread t5=new Thread(count,"线程五"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }
4.2使用同步方法
class Count implements Runnable{ private volatile int count=1; private static Object oj = new Object(); public void run() { while (count<=1000){ sole(); } } public synchronized void sole(){//这把锁的锁对象就是this if(count<=1000) { count = count + 1; System.out.println(Thread.currentThread().getName() + ",count:" + count); } } } public class ThreadTest { public static void main(String[] args) { Count count=new Count(); Thread t1=new Thread(count,"线程一"); Thread t2=new Thread(count,"线程二"); Thread t3=new Thread(count,"线程三"); Thread t4=new Thread(count,"线程四"); Thread t5=new Thread(count,"线程五"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }