JAVA初学者如何理解多线程之synchronized关键字
synchronized关键字是Java多线程模型下的一个关键字,其英文意思是同步的意思,主要运用在资源共享当中,也就是说,
当你需要使用多个线程对象共享资源的时候,synchornized关键字就可以大显身手了。
初学者学到线程,对线程应该有所了解,线程是进程的一部分,所以线程和进程具有许多相同的特性,其中最突出的就是线程的并发性(在Java语言中,并发并不是指同时发生,而是他们之间有顺序的,只不过其运行速度让我们看见像是一起执行的一样,这点需要清楚)。
既然不是一起执行,那么肯定就会有先后顺序,那么谁先谁后呐?答案是不明确的,虽说线程之间也有优先级之分,但优先级只是增加先被执行的概率而已,并不是谁高谁就一定比低的先执行,就如同量子力学一样具有不确定性原理(遇事不决,量子力学)。
这就是多线程另一个特点——抢占式,(运气总是留给有准备和争取机会的人),但是抢占式也会出现许多明显的问题,话不多说,上代码,我就用众所周知,便于理解的窗口卖票的举例(又是充当卖票员工的一天)。
首先需要创建一个线程,创建线程的有三种方式,一、使用Thread类创建线程 二、使用Runnable接口创建 三、使用Callable创建(不常用)
我们这里使用的是Runnable创建的线程,其实也是有原因的,Runnable接口的优点在于:
一、避免单继承带来的局限性,一个类可以实现多个接口,但只能继承一个父类
二、适合资源的共享(这里使用也是为了更好的演示synchronizd的作用)
定义好线程的Run方法时候,创建线程对象
这里我们可以看到,既然是一起卖出共享的100张票,为什么却出现了重复的邮票,和负数邮票
这就是抢占式所带来的问题:多线程执行过程中,大概率不会管一个线程对象有没有执行完成,如在窗口2在卖最后一张票的时候,没执行完成的条件下,窗口2,窗口3也进入卖最后一张票的线程当中,所以出现输出同一张票、和输出负数票的结果(循环是先自减后输出)
如何解决这种情况,是今天要讲的重点,那就是上锁,synchronized关键字就在其中充当了锁的作用
上锁的方式有两种:一、同步代码块 二、同步函数
一、同步代码块,语法结构如下:
synchronized(锁对象){
需要同步的代码
}
运行时进入代码块需要获得锁对象,如果没有则需要等待,等到上一个被执行完成释放锁对象的时候才能进入(如上厕所,门上了锁肯定有人,有人肯定要等得嘛)
第二个是:同步函数,语法结构如下:
synchronized 函数返回值 函数名([参数]){
需要被同步的代码
}
使用synchronized关键字之后的效果:
如有需要纠正的地方欢迎补充;