作者 :卿笃军
原文地址:http://blog.csdn.net/qingdujun/article/details/39348093
本文演示,Tread多线程安全问题,以及一种解决多线程安全方式(线程同步)。
1)一个线程不安全的Demo
2)线程同步
一、小Demo演示引出线程安全问题:
package thread.runable1.qdj; //1.定义类实现Runnable接口 class RunDemo1 implements Runnable { private int x = 5; //2.覆盖Runnable接口中的run方法 //将线程代码存放在run中 public void run() { while (true) { if (x > 0) { //添加sleep(),注意:sleep()会抛出异常 try { Thread.sleep(10); //让线程睡眠10ms } catch (Exception e) { e.printStackTrace(); } System.out.println("Runnable:"+x); --x; } } } } public class CRunableDemo1 { public static void main(String[] args) { RunDemo1 r = new RunDemo1(); //3.通过Thread类建立线程对象,并将Runnable接口的子类对象作为参数 Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); Thread t4 = new Thread(r); //4.使用start开启线程 t1.start(); t2.start(); t3.start(); t4.start(); } }
运行显示结果:
以上打印出了0,-1,-2等数字,发现没?(线程出问题了吧!!!)
出问题的原因是什么呢?
线程1进入,强制睡眠10ms;此时线程2进入,又强制睡眠10ms;线程3进入又强制睡眠10ms;线程4进入再强制睡眠10ms;
注意,以上4个线程睡眠时都已经进入了if语句,进入的时候x>0还是成立的;
好了,线程1醒来,开始打印打印5,4,3,2,这时候--x还没执行,线程2就醒来了,抢去了cpu的执行权.....................
二、线程同步
问题:对于上面的问题,我们是不是可以采取一个这样的措施?当线程1执行run代码段的时候,我们不让其他的线程来执行,直到线程1执行完,其他的线程才可以进入。
解决方案:好在Java里面本来就有这样的函数,将代码段包裹起来,就可以达到上面问题描述的效果。函数名:synchronized,需要一个参数,随便传个对象就ok了。
package thread.runable1.qdj; //1.定义类实现Runnable接口 class RunDemo1 implements Runnable { private int x = 5; Object obj = new Object(); //2.覆盖Runnable接口中的run方法 //将线程代码存放在run中 public void run() { while (true) { synchronized (obj) { if (x > 0) { //添加sleep(),注意:sleep()会抛出异常 try { Thread.sleep(10); //让线程睡眠10ms } catch (Exception e) { e.printStackTrace(); } System.out.println("Runnable:"+x); --x; } } } } } public class CRunableDemo1 { public static void main(String[] args) { RunDemo1 r = new RunDemo1(); //3.通过Thread类建立线程对象,并将Runnable接口的子类对象作为参数 Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); Thread t4 = new Thread(r); //4.使用start开启线程 t1.start(); t2.start(); t3.start(); t4.start(); } }
运行结果显示:
参考文献:Java视频 毕向东 主讲
原文地址:http://blog.csdn.net/qingdujun/article/details/39348093
时间: 2024-10-23 18:30:10