Java-初步认识-第十三章-同步的好处和弊端

一. 同步的原因

synchronized的代码块的封装作用,我们已经认识到了。但是它到底是怎么起到作用,现在来讨论一下。

这里面有一个对象,我们先简单地将它理解为标志位。这标志位怎么用的呢?

现在假想标志位有0和1,如果先来的默认值是1。这时,来了四个不同编号的线程,0~3。

0线程进来后,synchronized后面的标志位为1,(1代表着开着),进来后,就把1置为了0。标志位在0和1之间,进行了切换。

0和1可以理解为真假的假。当标志位为0的时候,后面的线程1,2,3读synchronized的时候,都进不来。

当0线程进来后,经过判断,开始执行语句,try里面有一个sleep语句。一旦0线程运行了sleep语句,cpu就开始切换到其他线程上了。

0线程释放了资格,释放了执行权。但是拿到执行权的其他线程,由于标志位为0,都进不来。这时,0线程醒了,执行完剩下的语句,就直接退出了。0线程刚推出的时候,就把标志位0变为了1。按照这个道理,1~3线程都是一样的过程。

这样一来,object就像锁一样。这是对象锁,或者同步锁。刚才说的标志位概念并不存在,真正的概念是锁。

为什么要放一个对象锁进来,后期要对同步中的线程进行监视,因为监视的方法都在锁上呢。

对象锁,同步地解决线程安全的原因。到这,同步的基本特点就介绍完了。

二. 同步的特点

线程里的问题很多,这里只是解决了部分问题。(同步应该说的是多个代码语句一起执行,比如这里的if判断,和try,以及输出语句)

0线程进到synchronized代码块中后,会一直持有cpu的执行权么?不会,如果一直持有,那么其他程序根本运行不了,比如说QQ,360....这就意味着,此时,cpu的执行权会切换到其他线程上,如1~3,但是无论这三个线程谁拿到执行权,都会被判断同步锁,判断完,进不去。相当于无效判断,所以效率会有点低。

这个效率低是可以在我们的承受范围之内的。

package test;
/*
 * 需求,卖票
 * 
 * 线程安全问题产生的原因
 * 前提:
 *1.多个线程在操作共享的数据。多线程哦
 *2.操作共享数据的线程代码有多条。共享数据,多个线程操作。
 *
 *当一个线程在执行操作共享数据的多条代码中,其他线程参与了运算
 *就会导致线程安全问题的产生
 *
 *解决思路:
 *
 *就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不可以参与运算的的
 *
 *必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
 *
 *在java中,用同步代码块解决这个问题
 *
 *同步代码块的格式:
 *synchronized(对象)
 *{
 *需要被同步的代码块
 *}
 *
 *同步的好处:解决了线程的安全问题
 *同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁
 *
 *同步的前提:
 *同步中必须有多个线程并使用同一个锁。
 */
class Ticket implements Runnable
{
	private  static int num = 10;
	Object obj = new Object();
	public void run() {
		
		while(true) 
		{	
			synchronized (obj)
			{
				if(num>0)
					
				{
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO: handle exception
					}
					System.out.println(Thread.currentThread().getName()+"..sale..."+num--);
				}
			}
			
		}
	}
}

public class RunnableDemo {

	public static void main(String[] args)
	{
		Ticket t = new Ticket();//创建一个线程任务对象
		
		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();
	}

}

猜你喜欢

转载自blog.csdn.net/fighting_future/article/details/80300016
今日推荐