`
LXL_yes777
  • 浏览: 11224 次
文章分类
社区版块
存档分类
最新评论

多线程(二)——线程同步synchronized

 
阅读更多

线程同步

1.线程同步定义

所谓线程同步,它的真实意思,其实是“排队”,几个线程要对同一资源进行操作时,必须排队依次来进行访问,而不是在同一时刻多个线程对共享资源同时操作。

 

2.问题引入

 

至于为什么要运用线程同步呢?就如我们在多线程(一)中提到的例子买火车票一样,如果多个线程同时去买票就有可能出现余票为负数的情况。

示例代码如下:

 

public class RunaableTest implements Runnable{

	int ticket=5;
	public static void main(String []args){
		RunaableTest rt=new RunaableTest();
		for(int i=0;i<3;i++){
			new Thread(rt).start();
		}
	}
	public void run(){
		while(true){
			if(ticket>0){
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("线程"+Thread.currentThread().getName()+"买票之后还有余票:ticket"+ticket--+"张");
			}
		}
	}
}

 

程序运行结果如下:



 

由以上例子可以看出,当我们让线程休眠一段时间,再去执行ticket--,这样在程序的最后出现了卖出负票的问题,这样显然是不对的,为什么会这样呢?我们可以猜测:在if循环中同一时刻至少存在两个线程,第一个线程还没来得及进行ticcket--操作时,第二个线程经过判断满足if循环条件即ticket>0也进入循环体内,这样一来就会出现其实没票了,但还能卖出票的情况。

 

3.解决办法

 

出现上面的问题,只是因为多个线程对if循环的条件同时进行了判断,所以在多线程操作同一个资源时我们只需要对其有一个限制,即设定同一时刻只能有一个线程去访问共享的资源,如此一来问题就可以轻松的解决了。

而在JAVA中我们可以通过关键字synchronized来解决这个问题,实现线程之间的同步。而synchronized的使用方法有两种,可以通过同步代码块和同步方法两种方式来完成。

 

1.同步代码块:

public  void run(){
		while(true){
			synchronized(this){
				if(ticket>0){
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程"+Thread.currentThread().getName()+"买票之后还有余票:ticket"+ticket--+"张");
				}
			}
		}
	}

 

 

2.同步方法:

public synchronized void run(){
		while(true){
			if(ticket>0){
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("线程"+Thread.currentThread().getName()+"买票之后还有余票:ticket"+ticket--+"张");
			}
		}
	}

 

    两种实现方式的运行结果是一样的,结果如下:



 

由此我们便可完成线程同步,解决多个线程同一时刻访问同一对象的问题啦!!!

 

PS:线程中还有死锁的概念,所谓死锁,就是指两个线程都在等对方完成。举个例子,假设只有一碗饭,一双筷子,二者合到一起,才能吃到饭,但是饭在甲的手中,而筷子在乙的手中,甲,乙都在等着对方先给,就这样僵持着,最终的结果是甲乙都吃不到饭,这就是死锁的概念。程序出现死锁的情况有可能是因为过多的同步,所以在多个线程共享同一资源进行同步的同时,也要注意避免出现死锁的状况哈。。。。。。

  • 大小: 6.6 KB
  • 大小: 5.2 KB
分享到:
评论

相关推荐

    Java多线程基础——Lock类

    Lock类是Java类来提供的功能,丰富的api使得Lock类的同步功能比synchronized的同步更强大。本文对此进行详细介绍,下面跟着小编一起来看下吧

    Java并发学习笔记(二)——Synchronized关键字与ReetrantLock同步锁

    一、Synchronized ...被Synchronized 关键字描述的方法或代码块在多线程环境下数据是同步的,即当获取到锁后先将内存复制到自己的缓存中操作,释放锁之前会把缓存中的数据复制到共享内存中,所以保证了可

    Java多线程编程 线程同步机制.docx

    锁正是基于这种思路实现的一种线程同步机制。 在对共享数据加锁后,每个线程在访问共享数据时必须先申请相应的锁。一旦获得锁后,就可以访问共享数据,并且一个锁同一时刻只能被一个线程持有,这意味着获得锁后不会...

    Lock锁的底层原理完整版

    Lock锁,一种线程同步机制,其主要功能是防止多个线程同时访问同一代码块,从而避免因并发问题引发的数据不一致或其他错误。...总的来说,Lock锁是Java多线程编程中的重要工具,能够有效保障程序运行的正确性和稳定性。

    Java SE实践教程 源代码 下载

    第6章 三头六臂——线程和同步的基本概念 109 6.1 讲解 110 6.1.1 什么是线程 110 6.1.2 创建线程 110 6.1.3 线程的生命周期 112 6.1.4 线程的优先级 114 6.1.5 中断线程 115 6.1.6 线程组 116 6.1.7 处理未...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    第6章 三头六臂——线程和同步的基本概念 109 6.1 讲解 110 6.1.1 什么是线程 110 6.1.2 创建线程 110 6.1.3 线程的生命周期 112 6.1.4 线程的优先级 114 6.1.5 中断线程 115 6.1.6 线程组 116 6.1.7 处理未...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    第6章 三头六臂——线程和同步的基本概念 109 6.1 讲解 110 6.1.1 什么是线程 110 6.1.2 创建线程 110 6.1.3 线程的生命周期 112 6.1.4 线程的优先级 114 6.1.5 中断线程 115 6.1.6 线程组 116 6.1.7 处理未...

    Java典型模块

    6.3 知识点扩展——线程的同步知识 6.3.1 为什么要使用同步机制 6.3.2 Synchronized的同步块 6.3.3 Synchronized的同步方法 6.3.4 死锁的问题 6.4 小结 第7章 生产者与消费者问题(线程通信知识) 7.1 生产者与消费...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...

    java经典面试2010集锦100题(不看你后悔)

    —————————————————————————————————————— 题目1: 下面不属于基本类型的是:c (选择1项) A) boolean B) long C) String D) byte 题目2:d 如下程序中: (1)public class ...

Global site tag (gtag.js) - Google Analytics