进程:进程是处在运行的程序
线程:进程里任务的执行路径
多线程:一个进程里有多个线程可以执行多个任务
线程安全问题:
先看一个售票例子
public class main{
public static void main(String[] args){
SellTickets thread1=new SellTickets("1号窗口");
SellTickets thread2=new SellTickets("2号窗口");
SellTickets thread3=new SellTickets("3号窗口");
//执行售票
thread1.start();
thread2.start();
thread3.start();
}
}
class SellTickets extends Thread{
static int num=100;
public SellTickets(String window){
super(window);
}
@Override
public void run(){
while(true){
if(num>0){
System.out.println(Thread.currentThread().getWindow()+"卖出了第"+num+"号票");
num--;
}else{
System.out.println("票已经售光");
break;
}
}
}
}
打印结果:1号窗口卖出了第100号票
3号窗口卖出了第100号票
3号窗口卖出了第98号票
3号窗口卖出了第97号票
3号窗口卖出了第96号票
我们会发现第100号票被卖了2次。
解决方案:给需要的代码块加上同步锁
synchronized (this) {
if(num>0){
System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
num--;
}else{
System.out.println("票已经售光");
break;
}
}
再看打印结果:
3号窗口卖出了第100号票
3号窗口卖出了第99号票
3号窗口卖出了第98号票
……
2号窗口卖出了第2号票
2号窗口卖出了第1号票
3号窗口卖出了第47号票
票已经售光
1号窗口卖出了第48号票
票已经售光
票已经售光
于是一共卖出了100张票
我们把这个问题叫作线程安全问题,那么为什么会出现线程安全问题呢?
这是因为线程抢占资源引起的,当1号窗口执行代码块中的任务时,还没执行完毕,即票数还未减到99,窗口3就抢占了cpu执行权,也执行代码块里的任务。此时第100号票相当于被卖了2次。当我们加上安全锁(synchronized)之后,代码块里的代码在某段时间里只能有一个线程可以执行。这就解决了线程安全问题!