学习线程后觉得不是那么好理解,特别是对多线程的理解。
现在就和大家分享一下我对多线程的理解:
卖票程序:运用线程的知识创建一个实现火车站卖火车票的类,注意在该类中不能出现多次卖同一张票,
或者某一张票没卖的情况。
现在我们来理解这个题目,假设有100张票,卖一张少一张,大致的可以这样理解
if(票数大于零) 第一行
{ 第二行
卖一张票; 第三行
票数减一; 第四行
}
单线程我们就不说了,不存在抢占运行的说法。如果是多线程呢?假设现在又A、B、C这三个窗口卖票,
也就是3个线程。现在A发现票数大于零,运行,刚运行完第三行,B发现票数大于零,运行,没运行完,
然后C又发现票数大于零,运行……这时候出现了什么结果?一票多卖!怎么解决这个问题呢?这就要
用到同步的知识点。
当时我看到这道题的时候我也很困惑,也不知道怎么理解。为什么会出现一票多卖,某一张没卖?觉得,
程序运行不都是一条一条的从前往后的运行吗?抢占的概念一出现,不大理解,就不懂它为什么会抢占。
后来在经过问在加上自己的理解,理解到:线程的运行权通过抢占的方式获得。一个程序运行到一半时
突然被另一个线程抢占了运行权,此时这个线程数据处理了一半,而另一个线程也在处理这个数据,那
么就会出现重复操作数据的现象,最终整个系统将会混乱。如果想要解决这个问题,就得用到同步。
不是说什么都需要同步,只需要找到最关键的步骤就可以,就像卖票,只要控制好票数,和卖一张减一张
就可以了。
同步块(synchronized)
格式:synchronized(类对象名a)
{
同步代码块:
}
功能:synchronized(类对象名a)的含义是:判断a是否已被其他线程霸占,如果发现已经被其他线程霸占
则当前线程陷入等待中,如果发现a没有被其他线程霸占,则当前线程霸占住a对象,并执行同步代码
块,在当前线程执行同步代码块时,其他线程将无法再执行同步代码块(因为当前线程已经霸占(锁定)
了a对 象),当前线程执行完同步代码块代码后,会主动释放对a对象的霸占,此时再和其他线程相互
竞争对a的霸占,最终cpu会选择其中的某一个线程执行……
最终导致的结果是:一个线程正在操作某资源的时候,将不允许其他线程操作该资源,即一次只允许一个线
程处理该资源。
class A implements Runnable {
private int tickets = 100;
String str = new String("haha");
public void run() {
while(true) {
synchronized(str) {
if(tickets > 0) {
//System.out.printf("%s线程正在卖出第%d张票",
// Thread.currentThread().getName(), tickets);
System.out.println(Thread.currentThread().getName() +
":" + tickets);
--tickets;
}
else
{
break;
}
}
}
}
}
public class TestTickets {
public static void main(String[] args) {
A a = new A();
Thread t1 = new Thread(a);
t1.start();
Thread t2 = new Thread(a);
t2.start();
Thread t3 = new Thread(a);
t3.start();
}
}
这样就能解决一票多卖和有票没卖的问题了。