黑马程序员——线程的安全问题
2015-04-28 23:53
169 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
线程出现安全问题的原因分析
是因为我们通过多个线程对同一数据进行操作时,它的时间片分配是随机的,有可能在票数递减后线程就将时间片让出,这时其它的线程在执行时,就会在原来票数基础上在递减。
在展示时就会出现同票或负数问题.
这是多线程存在的一些安全问题.
线程安全问题的产生的条件
1. 必须是多线程程序2. 多个线程操作同一个数据
3. 在操作同一个数据时有多条语句。
同步代码块的方式解决线程案例问题
解决线程安全问题的原理:在对于有可能产生线程安全的代码,我们进行控制,让线程在执行时,
其它的线程不可以访问,我的线程执行完成后,其它线程才可以使用.
对于我们线程案例问题:可以使用同步来解决.
同步代码块
同步方法
同步代码块的格式:
Synchronized(任意一个对象){
可能出现安全问题的代码
}
我们在测试程序中使用了同步代码块
<span style="font-size:14px;">package cn.itcast.test; //售票程序 implements Runnable //100张速度与激情7票,三个窗口售卖。显示出每一个窗口买的票是什么? //分析: //1.定义出100张票 //2.定义窗口做售票操作 //3.有三个窗口来售票---需要三个线程,而线程中要执行的操作就是售票。 public class SellTicketDemo2 implements Runnable { private boolean flag = true; // 1.定义100张票 private int ticketNum = 100; Object obj = new Object(); // 2.定义一个售票操作 public void sellTicket() { // 第二个第三个线程在这个位置等待 synchronized (obj) { if (ticketNum > 0) { // 判断有票才卖 System.out.println("售出了第" + (ticketNum) + "张票"); // 将票递减 try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } ticketNum--; } else { stopSellTicket();// 停止售票 // Thread.currentThread().stop(); } } } @Override public void run() { while (flag) { sellTicket(); } } // 停止售票 public void stopSellTicket() { flag = false; } }</span>
同步代码块的锁及同步方法应用和锁的问题
使用同步方法来解决问题同步方法格式 :
在方法的修饰符上使用一个synchronized就可以。
public synchronized void sellTicket(){} 这就是一个同步方法.
与同步代码块的区别:
它们的原理是一样的,只不过同步代码块可以控制的范围更精确。
而同步方法只是对一个方法时行了同步。
问题:同步方法也要使用一个锁,它的锁是什么?
对于同步方法来说,它所使用的锁对象就是this.
注意:这时的同步方法不能是静态的,如果是静态的它的锁又是什么哪?
是本类的Class对象。
Java中的Class对象怎样获取?
简单获取方式就是 类名.class
package cn.itcast.test; //售票程序 implements Runnable //100张速度与激情7票,三个窗口售卖。显示出每一个窗口买的票是什么? //分析: //1.定义出100张票 //2.定义窗口做售票操作 //3.有三个窗口来售票---需要三个线程,而线程中要执行的操作就是售票。 //使用同步方法來解決线程安全问题 public class SellTicketDemo3 implements Runnable { private static boolean flag = true; // 1.定义100张票 private static int ticketNum = 100; int x = 0; // 2.定义一个售票操作 同步方法 public static synchronized void sellTicket() { if (ticketNum > 0) { // 判断有票才卖 System.out.println("售出了第" + (ticketNum) + "张票"); // 将票递减 try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } ticketNum--; } else { stopSellTicket();// 停止售票 } } // 它不是同步方法 在这个方法的同步块中所使用的锁是obj. public void sellTicket2() { synchronized (SellTicketDemo3.class) { if (ticketNum > 0) { // 判断有票才卖 System.out.println("售出了第" + (ticketNum) + "张票"); // 将票递减 try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } ticketNum--; } else { stopSellTicket();// 停止售票 } } } @Override public void run() { while (flag) { if (x % 2 == 0) { sellTicket(); } else { sellTicket2(); } x++; } } // 停止售票 public static void stopSellTicket() { flag = false; } }
同步代码块(和同步方法)解决线程线程案例问题的解释
就是对我们在多线程程序中要操作的共享数据及对其进行操作的语句进行了加锁操作,简单说,就是一个线程在执行这些代码时,其它的线程不能执行。
同步代码块可以对方法中一部分代码进行加锁。
而同步 方法是将所有的方法内的代码进行了加锁。
同步的特点及好处和弊端 以及同步代码块与同步方法选择
使用一个对象做为锁,所有的线程使用同一个锁,当一个线程使用它时,其它线程等待。优点:可以解决我们多线程程序的安全问题.
缺点:使用了同步,会降低多线程程序的性能。并且有可能出现死锁问题.
同步代码块与同步方法使用哪一个?
同步代码块可以替换同步方法,同步方法不能替代同步代码块,所以在
精度控制上,同步代码块会更好,并且,使用同步代码块的效率也比较高。
所以我们一般选择使用同步代码块。
相关文章推荐
- 黑马程序员——Java多线程之线程安全问题
- 黑马程序员-多线程(线程的安全问题与锁的理解)
- 黑马程序员------多线程(No.1)(概述、线程的创建、安全问题、同步锁、同步函数)
- 黑马程序员 第27天 多线程安全问题 线程停止
- 黑马程序员——java中两个线程对同一个数据做不同操作的安全问题
- 黑马程序员 学习笔记六:线程间的通信以及通信安全问题
- 黑马程序员之线程安全问题与单例模式
- 黑马程序员-(多线程)了解线程与如何解决线程同步到来的安全问题!(面试)
- 单例模式中的线程安全问题
- 单例带来的线程安全问题
- Servlet的线程安全问题
- 黑马程序员:多线程的介绍、应用及由安全问题引出的同步代码块介绍
- SimpleDateFormat的线程安全问题与解决方案
- java线程安全问题之静态变量、实例变量、局部变量
- Servlet和JSP的线程安全问题
- 从volatile说到i++的线程安全问题
- 实例解析Java中的synchronized关键字与线程安全问题
- DateFormat的线程安全问题
- java多线程(1):线程的创建和多线程的安全问题
- servlet的线程安全问题