【Java多线程】多线程的线程安全及同步(synchronized)用法
来源:互联网 发布:网络21成功系统挣钱么 编辑:程序博客网 时间:2024/05/16 20:54
Q:什么是线程安全问题?
A:当多个线程同时共享同一个全局变量或静态变量,改变变量的数据时,可能会发生数据冲突问题,也就是线程安全问题。读取变量不会发生数据冲突。
Q:当有线程安全问题时,应该怎样处理?
A:把对全局变量或静态变量做修改的代码放入同步代码块,即synchronized(){}。
PS:synchronized 修饰方法使用锁是当前this锁。synchronized 修饰静态方法使用锁是当前类的字节码文件。
案例:售票系统,假设有两个窗口同时售票,使用多线程模拟售票。
SellTicket.java
运行结果片段
public class SellTicket implements Runnable{// 100张票private int ticketCount = 100;// 使用线程模拟售票窗口@Overridepublic void run() {// 死循环,窗口不停卖票while (true) {// 未在操作变量的代码加锁(同步)// 如果票数为零,则跳出循环,结束线程(关闭窗口,停止售票)if (ticketCount > 0) {//try {//Thread.sleep(0);//} catch (Exception e) {//e.printStackTrace();//}System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - ticketCount + 1) + "张票.");ticketCount--;} else {break;}}}public static void main(String[] args) {// 单例,只有一个ticketCountSellTicket st = new SellTicket();// 创建两个线程并运行Thread t1 = new Thread(st);Thread t2 = new Thread(st);t1.start();t2.start();}}
运行结果片段
Thread-0,出售 第1张票.Thread-0,出售 第2张票.Thread-0,出售 第3张票.Thread-0,出售 第4张票.Thread-0,出售 第5张票.Thread-1,出售 第1张票.Thread-1,出售 第7张票.Thread-1,出售 第8张票.Thread-1,出售 第9张票.
Thread-1,出售 第98张票.Thread-1,出售 第99张票.Thread-1,出售 第100张票.Thread-0,出售 第40张票.可以看到线程0已经卖出了第1张票,可是线程1也卖出了第1张票,而最后线程1已经卖出了第100张票,线程0又卖出了第40张票。
让线程每卖出一张票睡眠100毫秒
运行结果片段
// 如果票数为零,则跳出循环,结束线程(关闭窗口,停止售票)if (ticketCount > 0) {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - ticketCount + 1) + "张票.");ticketCount--;} else {break;}
运行结果片段
Thread-1,出售 第99张票.Thread-0,出售 第100张票.Thread-1,出售 第101张票.这次除了出现以上的情况,还卖出了第101张票。
这就是两个线程在同时操作一个变量,造成的线程安全问题。
怎么让线程安全?使用同步代码块(加锁)
SellTicket.java
public class SellTicket implements Runnable{// 100张票private int ticketCount = 100;// 同步代码块的锁private Object obj = new Object();// 使用线程模拟售票窗口@Overridepublic void run() {// 死循环,窗口不停卖票while (true) {// 在操作变量的代码加obj锁(同步),当某个线程开始运行里面代码时,会得到锁。// 其他线程如果想运行同样代码,需等得到锁的代码运行完毕解锁后,再得到锁执行。synchronized(obj) {// 如果票数为零,则跳出循环,结束线程(关闭窗口,停止售票)if (ticketCount > 0) {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - ticketCount + 1) + "张票.");ticketCount--;} else {break;}}}}public static void main(String[] args) {// 单例,只有一个ticketCountSellTicket st = new SellTicket();// 创建两个线程并运行Thread t1 = new Thread(st);Thread t2 = new Thread(st);t1.start();t2.start();}}
运行结果片段
Thread-0,出售 第92张票.Thread-0,出售 第93张票.Thread-0,出售 第94张票.Thread-0,出售 第95张票.Thread-0,出售 第96张票.Thread-0,出售 第97张票.Thread-1,出售 第98张票.Thread-1,出售 第99张票.Thread-1,出售 第100张票.同步后线程安全问题解决了。
阅读全文
0 0
- 【Java多线程】多线程的线程安全及同步(synchronized)用法
- java线程多线程同步机制(synchronized)
- Java多线程,线程同步synchronized,线程死锁【线程池常规用法】多线程并发处理
- JAVA 多线程--线程同步安全
- 【Java多线程】synchronized与线程安全
- Java多线程:线程同步与关键字synchronized
- java多线程之synchronized(线程同步)
- 【Java多线程】-线程同步synchronized和volatile
- Java多线程-3 线程同步之synchronized
- Java多线程同步 – synchronized 用法
- java 多线程 同步 synchronized 的个人理解和用法
- JAVA学习笔记--多线程(三)synchronized实现线程同步
- Java多线程(二):线程同步synchronized和volatile
- java-多线程 | 线程安全和线程同步
- Java多线程 synchronized的用法
- java Synchronized 多线程同步
- java多线程同步,Synchronized
- Java 多线程同步--synchronized
- java 虚拟机加载类的途径
- C# DataGridView控件使用示例
- 【Linux学习笔记】1:RHEL的安装和与XShell的连接
- vue-表单操作
- 排序算法
- 【Java多线程】多线程的线程安全及同步(synchronized)用法
- uestc 811 GCD 杜教筛 + 自然幂和
- JAVA批量更改文件的后缀名
- ThingInJava-enum笔记
- codevs1557 热浪[SPFA模板]
- 迭代器模式
- 学习1
- mac操作技巧
- Codeforces Educational Round 27 总结