/**
* 通过画图分析,分析上一篇博文中错票产生的原因:
* 已经判断为票数了,线程被阻塞了,先一次被切换到不需要判断了。
* 局部变量不会出现数字错乱的现象,而成员变量会出现数组出现负数的现象。
*
* 安全的问题产生的原因:
* 1.多个线程在操作共享数据。
* 2.操作共享数据的代码有多条。
*
* 一个线程在执行多条操作共享数据的过程当中,其他线程参与的运算,这时就会产生安全问题。
*
* 想要分析线程当中是否有安全问题?
* 依据:线程任务当中有没有共享的数据,该数据是否被多条语句操作。
*
* 这个安全问题的解决方案?
* 只要保证一个线程在执行多条共享数据的语句时,其他的线程不能参与运算即可。
* 当该线程执行完之后,其他线程在来处理这个语句。
*
* 代码体现:
* java给我们提供了具体的代码:就是同步代码块。
* 格式:synchronized(对象){ //这个对象可以是任意的对象
* //需要被同步执行的语句
* }
*
* 同步的原理:其实就是将需要同步的代码进行了封装,然后在将封装的代码块之上加了一把锁。
*
* 同步的好处:解决了多线程的安全问题。
* 同步的弊端:会降低性能。
*
* 一种现象,出现了多线程的安全性问题,为了解决加了同步,发现问题依旧,产生这个现象的原因是什么?
*
* 同步的前提
* 1.必须要保证同步中有多个线程,因为同步中只有一个线程这个同步是没有任何意义的。
* 还需要注意把共享数据的多条代码都放在同步代码块当中。
* 2.必须要保证多线程在同步中使用的是同一把锁。
*
* */
package com.work.wor01;
class Ticket1 implements Runnable{
private int num = 100;
Object obj = new Object();
@Override
public void run() {
while(true){
synchronized (obj) {//同步代码块 , 解决了因为下面两行sleep()产生的产生负票问题。
if(num>0){
try {
// 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)会产生负数票
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"...sale"+num--);
}else{
break;
}
}
}
}
}
public class ThreadTicket02 {
public static void main(String[] args) {
Ticket1 t = new Ticket1();
//Thread类的对象和Thread类的子类的对象都是线程的对象。
//但是t并不是线程的对象。
//向四个线程当中传入的是同一个t对象,是因为线程执行的是同样的任务。
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
多线程——引入同步代码块解决窗口卖票产生负票的问题
最新推荐文章于 2021-11-13 17:06:44 发布