java 多线程学习笔记之 线程互斥
2015-03-24 02:37
274 查看
许多线程共享同一数据,这种情况在现实的生活中也是经常发生的,比如火车站的火车票售票系统。火车票售票系统是一个常年运行的系统,为了满足乘客的需求,我们不能只设一个窗口,必须设很多的售票窗口,每个售票窗口就像一个线程,它们各自运行,共同访问相同的数据——火车票的数量,下面我们用多线程模仿一下火车票售票系统:
相关测试代码:
相关测试结果:
程序输出了线程0、1、2、4四个线程从第100张票卖到第1张票的过程,存在火车票多次重复出售的问题,这是在实际火车票出售中,是绝对不允许出现这样的问题。遇到了不对的情况,我们就应该得想办法解决它,在Java中运用互斥的方法解决这个问题。
什么叫互斥?
多线程同时共享同一数据(内存区域),每个线程都尝试操作该数据,从而导致数据被破坏,这种现象称为争用条件(互斥)。
java 如何解决互斥问题?
互斥操作的控制,Java提供了关键字synchronized进行的。synchronized可以修饰方法,也可以修饰代码段。其代表的含义就是:进入他修饰的这段代码内的线程必须先去获取一个特定对象的锁定标示,并且虚拟机保证这个标示一次只能被一条线程拥有。
进过上面的描述,来进行修改我们的Ticker类
以上结果才算是正确的。
今天已经完成java 多线程学习之(互斥),下一讲,准备说(java 多线程之同步)
相关测试代码:
package com.example.ticker; public class Ticker { // 初始化火车票数量 private int tickers = 0; public int getTickers() { return tickers; } public void setTickers(int tickers) { this.tickers = tickers; } // 初始化构造函数 public Ticker(int tickers) { super(); this.tickers = tickers; } // 售票方法 public void sell() { if (tickers > 0) { System.out.println("sell tickets:" + tickers); tickers--; } } }
package com.examplex.threadstate; import com.example.ticker.Ticker; public class TicketRunnable implements Runnable { private Ticker ticker; private String name; public Ticker getTicker() { return ticker; } public void setTicker(Ticker ticker) { this.ticker = ticker; } public String getName() { return name; } public void setName(String name) { this.name = name; } public TicketRunnable(String name, Ticker ticker) { super(); this.ticker = ticker; this.name = name; } @Override public void run() { // 死循环 while (true) { // 条件判断 if (ticker.getTickers() > 0) { System.out.println("当前线程为:" + this.name); ticker.sell(); } } } }
package com.example.main; import com.example.ticker.Ticker; import com.examplex.threadstate.MyRunnable; import com.examplex.threadstate.MyThread; import com.examplex.threadstate.TicketRunnable; public class TestMain { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Ticker ticker = new Ticker(100); Thread thread1 = new Thread(new TicketRunnable("线程一", ticker)); Thread thread2 = new Thread(new TicketRunnable("线程二", ticker)); Thread thread3 = new Thread(new TicketRunnable("线程三", ticker)); Thread thread4 = new Thread(new TicketRunnable("线程四", ticker)); thread1.start(); thread2.start(); thread3.start(); thread4.start(); } }
相关测试结果:
当前线程为:线程一 sell tickets:100 当前线程为:线程一 当前线程为:线程三 sell tickets:99 当前线程为:线程一 sell tickets:98 当前线程为:线程一 sell tickets:97 当前线程为:线程一 sell tickets:96 当前线程为:线程一 sell tickets:95 当前线程为:线程一 sell tickets:94 当前线程为:线程一 sell tickets:93 当前线程为:线程一 sell tickets:92 当前线程为:线程一 sell tickets:91 当前线程为:线程一 sell tickets:90 当前线程为:线程一 sell tickets:89 当前线程为:线程一 sell tickets:88 当前线程为:线程一 sell tickets:87 当前线程为:线程一 sell tickets:86 当前线程为:线程一 sell tickets:85 当前线程为:线程一 sell tickets:84 当前线程为:线程一 sell tickets:83 当前线程为:线程一 sell tickets:82 当前线程为:线程一 sell tickets:81 当前线程为:线程一 sell tickets:80 当前线程为:线程一 sell tickets:79 当前线程为:线程一 sell tickets:78 当前线程为:线程一 sell tickets:77 当前线程为:线程一 sell tickets:76 当前线程为:线程一 sell tickets:75 当前线程为:线程一 sell tickets:74 当前线程为:线程一 sell tickets:73 当前线程为:线程一 sell tickets:72 当前线程为:线程一 sell tickets:71 当前线程为:线程一 sell tickets:70 当前线程为:线程一 sell tickets:69 当前线程为:线程一 sell tickets:68 当前线程为:线程一 sell tickets:67 当前线程为:线程一 sell tickets:66 当前线程为:线程一 sell tickets:65 当前线程为:线程一 sell tickets:64 当前线程为:线程一 sell tickets:63 当前线程为:线程一 sell tickets:62 当前线程为:线程一 sell tickets:61 当前线程为:线程一 sell tickets:60 当前线程为:线程一 sell tickets:59 当前线程为:线程一 sell tickets:58 当前线程为:线程一 sell tickets:57 当前线程为:线程一 sell tickets:56 当前线程为:线程一 sell tickets:55 当前线程为:线程一 sell tickets:54 当前线程为:线程一 sell tickets:53 当前线程为:线程一 sell tickets:52 当前线程为:线程一 sell tickets:51 当前线程为:线程一 sell tickets:50 当前线程为:线程一 sell tickets:49 当前线程为:线程一 sell tickets:48 当前线程为:线程一 sell tickets:47 当前线程为:线程一 当前线程为:线程四 sell tickets:46 当前线程为:线程一 sell tickets:45 当前线程为:线程一 sell tickets:44 当前线程为:线程一 当前线程为:线程二 sell tickets:43 当前线程为:线程二 sell tickets:42 当前线程为:线程二 sell tickets:41 当前线程为:线程二 sell tickets:40 当前线程为:线程二 sell tickets:39 当前线程为:线程二 sell tickets:38 当前线程为:线程二 sell tickets:37 当前线程为:线程二 sell tickets:36 当前线程为:线程二 sell tickets:35 当前线程为:线程二 sell tickets:34 当前线程为:线程二 sell tickets:33 当前线程为:线程二 sell tickets:32 当前线程为:线程二 sell tickets:31 当前线程为:线程二 sell tickets:30 当前线程为:线程二 sell tickets:29 当前线程为:线程二 sell tickets:28 当前线程为:线程二 sell tickets:27 当前线程为:线程二 sell tickets:26 当前线程为:线程二 sell tickets:25 当前线程为:线程二 sell tickets:24 当前线程为:线程二 sell tickets:23 当前线程为:线程二 sell tickets:22 当前线程为:线程二 sell tickets:21 当前线程为:线程二 sell tickets:20 sell tickets:99 当前线程为:线程三 sell tickets:18 当前线程为:线程三 sell tickets:17 当前线程为:线程三 sell tickets:16 当前线程为:线程三 sell tickets:15 当前线程为:线程三 sell tickets:14 当前线程为:线程三 sell tickets:13 当前线程为:线程三 sell tickets:12 当前线程为:线程三 sell tickets:11 当前线程为:线程三 sell tickets:10 当前线程为:线程三 sell tickets:9 当前线程为:线程三 sell tickets:8 当前线程为:线程三 sell tickets:7 当前线程为:线程三 sell tickets:6 当前线程为:线程三 sell tickets:5 当前线程为:线程三 sell tickets:4 当前线程为:线程三 sell tickets:3 当前线程为:线程三 sell tickets:2 当前线程为:线程三 sell tickets:1 当前线程为:线程二 sell tickets:43 sell tickets:43
程序输出了线程0、1、2、4四个线程从第100张票卖到第1张票的过程,存在火车票多次重复出售的问题,这是在实际火车票出售中,是绝对不允许出现这样的问题。遇到了不对的情况,我们就应该得想办法解决它,在Java中运用互斥的方法解决这个问题。
什么叫互斥?
多线程同时共享同一数据(内存区域),每个线程都尝试操作该数据,从而导致数据被破坏,这种现象称为争用条件(互斥)。
java 如何解决互斥问题?
互斥操作的控制,Java提供了关键字synchronized进行的。synchronized可以修饰方法,也可以修饰代码段。其代表的含义就是:进入他修饰的这段代码内的线程必须先去获取一个特定对象的锁定标示,并且虚拟机保证这个标示一次只能被一条线程拥有。
进过上面的描述,来进行修改我们的Ticker类
package com.example.ticker; public class Ticker { //初始化火车票数量 private int tickers=0; private Object lock=new Object(); public int getTickers() { return tickers; } public void setTickers(int tickers) { this.tickers = tickers; } //初始化构造函数 public Ticker(int tickers) { super(); this.tickers = tickers; } //售票方法 public void sell(){ synchronized(lock){ if(tickers>0){ System.out.println("sell tickets:"+tickers); tickers--; } } } }演示结果:
当前线程为:线程一 sell tickets:100 当前线程为:线程一 sell tickets:99 当前线程为:线程二 sell tickets:98 当前线程为:线程二 sell tickets:97 当前线程为:线程二 sell tickets:96 当前线程为:线程二 sell tickets:95 当前线程为:线程二 sell tickets:94 当前线程为:线程二 sell tickets:93 当前线程为:线程二 sell tickets:92 当前线程为:线程二 sell tickets:91 当前线程为:线程二 sell tickets:90 当前线程为:线程二 sell tickets:89 当前线程为:线程二 sell tickets:88 当前线程为:线程二 sell tickets:87 当前线程为:线程二 sell tickets:86 当前线程为:线程二 sell tickets:85 当前线程为:线程二 sell tickets:84 当前线程为:线程二 sell tickets:83 当前线程为:线程二 sell tickets:82 当前线程为:线程二 sell tickets:81 当前线程为:线程二 sell tickets:80 当前线程为:线程二 sell tickets:79 当前线程为:线程二 sell tickets:78 当前线程为:线程二 sell tickets:77 当前线程为:线程二 当前线程为:线程一 sell tickets:76 当前线程为:线程二 sell tickets:75 当前线程为:线程一 sell tickets:74 当前线程为:线程二 sell tickets:73 当前线程为:线程一 sell tickets:72 当前线程为:线程二 sell tickets:71 当前线程为:线程一 sell tickets:70 当前线程为:线程二 sell tickets:69 当前线程为:线程一 当前线程为:线程四 当前线程为:线程三 sell tickets:68 当前线程为:线程二 sell tickets:67 当前线程为:线程二 sell tickets:66 当前线程为:线程二 sell tickets:65 当前线程为:线程二 sell tickets:64 当前线程为:线程二 sell tickets:63 当前线程为:线程二 sell tickets:62 当前线程为:线程二 sell tickets:61 当前线程为:线程二 sell tickets:60 当前线程为:线程二 sell tickets:59 当前线程为:线程二 sell tickets:58 当前线程为:线程二 sell tickets:57 当前线程为:线程二 sell tickets:56 当前线程为:线程三 sell tickets:55 当前线程为:线程四 sell tickets:54 当前线程为:线程一 sell tickets:53 当前线程为:线程四 sell tickets:52 当前线程为:线程三 sell tickets:51 当前线程为:线程二 sell tickets:50 当前线程为:线程三 sell tickets:49 当前线程为:线程四 sell tickets:48 当前线程为:线程一 sell tickets:47 当前线程为:线程四 sell tickets:46 当前线程为:线程三 sell tickets:45 当前线程为:线程三 sell tickets:44 当前线程为:线程三 sell tickets:43 当前线程为:线程三 sell tickets:42 当前线程为:线程三 sell tickets:41 当前线程为:线程三 sell tickets:40 当前线程为:线程三 sell tickets:39 当前线程为:线程三 sell tickets:38 当前线程为:线程三 sell tickets:37 sell tickets:36 当前线程为:线程二 sell tickets:35 当前线程为:线程二 sell tickets:34 当前线程为:线程二 sell tickets:33 当前线程为:线程二 sell tickets:32 当前线程为:线程二 sell tickets:31 当前线程为:线程二 sell tickets:30 当前线程为:线程二 sell tickets:29 当前线程为:线程二 sell tickets:28 当前线程为:线程二 sell tickets:27 当前线程为:线程二 sell tickets:26 当前线程为:线程二 sell tickets:25 当前线程为:线程二 sell tickets:24 当前线程为:线程二 sell tickets:23 当前线程为:线程二 sell tickets:22 当前线程为:线程二 sell tickets:21 当前线程为:线程二 sell tickets:20 当前线程为:线程二 sell tickets:19 当前线程为:线程二 sell tickets:18 当前线程为:线程二 sell tickets:17 当前线程为:线程二 sell tickets:16 当前线程为:线程二 sell tickets:15 当前线程为:线程二 sell tickets:14 当前线程为:线程二 sell tickets:13 当前线程为:线程二 当前线程为:线程三 sell tickets:12 当前线程为:线程四 sell tickets:11 当前线程为:线程一 sell tickets:10 当前线程为:线程四 sell tickets:9 当前线程为:线程三 sell tickets:8 当前线程为:线程二 sell tickets:7 当前线程为:线程三 sell tickets:6 当前线程为:线程四 sell tickets:5 当前线程为:线程一 sell tickets:4 当前线程为:线程四 sell tickets:3 当前线程为:线程三 sell tickets:2 当前线程为:线程二 sell tickets:1
以上结果才算是正确的。
今天已经完成java 多线程学习之(互斥),下一讲,准备说(java 多线程之同步)
相关文章推荐
- java多线程学习笔记3
- JAVA多线程学习笔记
- 学习笔记 java多线程 信号量(Semaphore),死锁
- Java学习笔记(多线程)
- Java多线程学习笔记
- JAVA学习笔记之多线程
- 学习java多线程的笔记4--传智播客_张孝祥_空中网挑选实习生的面试题(来源于视频)
- JAVA多线程学习笔记—1
- 学习笔记 java多线程(四)线程间协作
- JAVA学习笔记————多线程
- [零散篇]Java学习笔记---Java的Socket网络编程以及多线程
- 学习java多线程的笔记1--Thread(Runnable t)与重写run()方法等
- Java学习笔记---多线程
- Java学习笔记9——多线程
- Java多线程学习笔记1
- Java 多线程编程 学习笔记
- 黑马程序员java学习笔记之四(java多线程总结)
- 黑马程序员---java多线程 学习笔记
- 学习笔记 - java.util.concurrent 多线程框架(引)
- java学习笔记1017---多线程