Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
2011-10-07 16:15
761 查看
下面的程序会逐步引出synchronized的用法:
[例]
结论:
使用Runnable接口创建多线程,适合多个相同的程序代码的线程去处理分享同一个资源的情况,把虚拟CPU(线程)同程序的代码数据有效分离,较好体现了面向对象的设计思想.
【多线程安全问题考虑】
程序像上面那样写并不安全,输出的结果有可能输出“售出负号票”,理由:假设Thread-0线程执行到while语句里时,这时恰巧tk=1;突然停了.切换到Thread-1线程,也是运行到while语句里突然切换到了Thread-2线程,这样while语句里有三个线程有待执行,tk=1,等这三个线程执行完毕tk就变成负数了.下面我们用sleep()来模拟这个假设:
多次运行TicketMan类调试,结果都不一样,有时出现0,有时不出现,模拟的程序已经达到要求了.那么针对这个卖票程序,到底怎样写才安全呢?这就是即将要引出的线程同步问题:synchronized关键字,代表这个方法枷锁,一次只能允许一个线程通过.比如线程A执行到synchronized代码快或方法体时,首先的工作就是检测有没有其他线程在执行该语句,有的话,就等其他线程出来后,再进去.
synchronized代码块的用法-synchronized(Object){}举例如下:
synchronized方法的用法需要与run()方法两个结合起来用:
[例]
class TicketMan { public static void main(String[]aresg) { Ticket t=new Ticket(); //创建4个线程 new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } } class Ticket implements Runnable { int tk=10; public void run() { while(tk>0) { System.out.println(Thread.currentThread().getName()+"窗口正在售出"+tk--+"号票."); } } } //输出结果:4个窗口,成功把10张票随机分配售完. /* Thread-0窗口正在售出10号票. Thread-1窗口正在售出7号票. Thread-1窗口正在售出5号票. Thread-3窗口正在售出8号票. Thread-2窗口正在售出9号票. Thread-3窗口正在售出3号票. Thread-3窗口正在售出1号票. Thread-1窗口正在售出4号票. Thread-0窗口正在售出6号票. Thread-2窗口正在售出2号票. */
结论:
使用Runnable接口创建多线程,适合多个相同的程序代码的线程去处理分享同一个资源的情况,把虚拟CPU(线程)同程序的代码数据有效分离,较好体现了面向对象的设计思想.
【多线程安全问题考虑】
程序像上面那样写并不安全,输出的结果有可能输出“售出负号票”,理由:假设Thread-0线程执行到while语句里时,这时恰巧tk=1;突然停了.切换到Thread-1线程,也是运行到while语句里突然切换到了Thread-2线程,这样while语句里有三个线程有待执行,tk=1,等这三个线程执行完毕tk就变成负数了.下面我们用sleep()来模拟这个假设:
class TicketMan { public static void main(String[]aresg) { Ticket t=new Ticket(); //创建4个线程 new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } } class Ticket implements Runnable { int tk=10; public void run() { while(tk>0) { try { Thread.sleep(1);//当前线程暂停1毫秒,处理器会去执行其他线程. } catch (Exception ex) { ex.printStackTrace();//输出造成异常更为详细的信息. } System.out.println(Thread.currentThread().getName()+"窗口正在售出"+tk--+"号票."); } } } //输出结果: /* Thread-0窗口正在售出9号票. Thread-2窗口正在售出7号票. Thread-3窗口正在售出8号票. Thread-1窗口正在售出10号票. Thread-2窗口正在售出5号票. Thread-0窗口正在售出6号票. Thread-2窗口正在售出2号票. Thread-1窗口正在售出3号票. Thread-3窗口正在售出4号票. Thread-2窗口正在售出0号票. Thread-0窗口正在售出1号票. */
多次运行TicketMan类调试,结果都不一样,有时出现0,有时不出现,模拟的程序已经达到要求了.那么针对这个卖票程序,到底怎样写才安全呢?这就是即将要引出的线程同步问题:synchronized关键字,代表这个方法枷锁,一次只能允许一个线程通过.比如线程A执行到synchronized代码快或方法体时,首先的工作就是检测有没有其他线程在执行该语句,有的话,就等其他线程出来后,再进去.
synchronized代码块的用法-synchronized(Object){}举例如下:
class TicketMan { public static void main(String[]aresg) { Ticket t=new Ticket(); //创建4个线程 new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } } class Ticket implements Runnable { int tk=10; String s=new String(""); public void run() { //run()方法体里千万别重置s对象,不然会放进很多线程进来,那就失去本来意义了,不妨把String s=new String("")移到run方法里试试看;. while(tk>0) { //synchronized代码块开始 synchronized(s) { //注意: synchronized()方法体里千万别重置s对象. if(tk>0) { try { Thread.sleep(50);//当前线程暂停1毫秒,处理器会去执行其他线程. } catch (Exception ex) { ex.printStackTrace();//输出造成异常更为详细的信息. } System.out.println(Thread.currentThread().getName()+"窗口正在售出"+tk--+"号票."); } } //synchronized代码块结束 } } }
synchronized方法的用法需要与run()方法两个结合起来用:
/* 语法: public synchronized void duMuQiao() {} public void run() { ..... 调用synchronized修改过的方法:duMuQiao(); ..... } 举例如下: */ class TicketMan { public static void main(String[]aresg) { Ticket t=new Ticket(); //创建4个线程 new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } } class Ticket implements Runnable { int tk=10; public void run() { while(tk>0) { duMuQiao();//调用synchronized修改过的方法:duMuQiao(); } } //synchronized方法开始 public synchronized void duMuQiao() //一个线程进入这个方法后 这个方法的大门就会暂时关闭(不许其他线程进入)直到这个线程走出这个方法后,该方法的大门才会敞开. { if(tk>0) { try { Thread.sleep(50);//当前线程暂停1毫秒,处理器会去执行其他线程. } catch (Exception ex) { ex.printStackTrace();//输出造成异常更为详细的信息. } System.out.println(Thread.currentThread().getName()+"窗口正在售出"+tk--+"号票."); } } //synchronized方法结束 }
相关文章推荐
- Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
- java多线程-多线程的安全问题-多线程同步代码块-锁Synchronized
- java 多线程 方法1 继承Thread 加入同步synchronized代码块
- java多线程-多线程同步代码块-银行存款实例-锁synchronized
- java中synchronize关键字的理解 在多线程环境下的应用: synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。 1. syn
- Java 多线程:synchronized 关键字 3ff0 用法(修饰类,方法,静态方法,代码块)
- Java多线程之Synchronized应用在static和非static方法上的区别
- Java基础知识 十七 (关于反射一些方法的总结)
- JAVA关于SET,GET的方法应用和一些问题
- Java的WEB应用性能问题定位方法总结(二):常见性能问题处理工具
- 关于java synchronized修饰方法时实现线程互斥遇到的问题
- Java的WEB应用性能问题定位方法总结(一):常见的性能指标分析
- Java中关于同步,异步,多线程,多线程同步,并发,并行的一些总结
- 学习总结:java面试方法重写详解,静态代码块和构造方法执行顺序问题
- java多线程之-----静态同步synchronized方法与synchronized(class) 代码块
- Java的WEB应用性能问题定位方法总结
- 关于java中子类,父类中,静态代码块: staic{},动态代码块:{},构造方法,类属性,对象属性等执行顺序做个总结:
- Java【多线程知识总结(9)】Timer类与TimerTask类的应用---模拟定时炸弹
- Java 多线程:synchronized 关键字用法(修饰类,方法,静态方法,代码块)
- Java的WEB应用性能问题定位方法总结:常见的性能指标分析 .