Java多线程基础篇(03)-synchronized关键字
2016-09-20 00:00
429 查看
摘要: Java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持。当任务要执行被synchronized关键字保护的代码片段的时候,它将检查锁是否可用,然后获取锁,执行代码,释放锁
Java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持。当任务要执行被synchronized关键字保护的代码片段的时候,它将检查锁是否可用,然后获取锁,执行代码,释放锁
共享资源一般是以对象形式存在的内存片段,但也可以是文件、输入/输出端口,或者是打印机设备。要控制对共享资源的访问,得先把它包装进一个对象。然后把所有要访问这个资源的方法标记为synchronized。如果某个任务处于一个对标记为synchronized方法的调用中,那么在这个线程从该方法返回之前,其他所有要调用类中任何标记synchronized方法的线程都会被阻塞。
不同线程对同步锁的访问是互斥的。也就是说,在某一个时刻,对象的同步锁只能被一个线程获取到!其他要获取该锁的线程都会被阻塞。知道线程释放了该锁,其他线程才能去获取同步锁,然后执行代码块。详细的synchronized工作原理请见博客:synchronized实现原理
一种比较好的办法是,如果某个变量由一个线程赋值,并由别的线程引用或赋值,那么所有对该变量的访问都必须在某个synchronized语句或者synchronized方法内,
有了synchronized关键字,多线程程序的运行结果将变得可以控制。synchronized关键字用于保护共享数据。所以编程时分清共享数据很重要。
运行结果:
结果说明:
run()方法中存在synchronized(this)代码块,而且t1和t2都是基于Runnable对象创建的线程。这就意味着,我们可以将synchronized(this)中的this看作是Runnable对象;因此t1和t2共享demo对象的同步锁。所以,当一个线程运行的时候,另外一个线程必须等待“运行中的线程”释放同步锁之后才能运行。特此说明:synchronized(this)中的this是指当前的类对象,即synchronized(this)所在的类对应的当前对象。它的作用是获取“当前对象的同步锁”。
1.引言
基本上所有的并发模式再解决线程冲突的时候,都是采用序列化访问共享资源的方案。这意味着在给定时刻只允许一个任务访问共享资源。通常这是通过在代码前面添加一条锁语句来实现的,这就使得在一段时间内只有一个任务可以运行这段代码。因为锁语句产生了一种互相排斥的效果,锁着这种机制常常被称为互斥量。Java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持。当任务要执行被synchronized关键字保护的代码片段的时候,它将检查锁是否可用,然后获取锁,执行代码,释放锁
共享资源一般是以对象形式存在的内存片段,但也可以是文件、输入/输出端口,或者是打印机设备。要控制对共享资源的访问,得先把它包装进一个对象。然后把所有要访问这个资源的方法标记为synchronized。如果某个任务处于一个对标记为synchronized方法的调用中,那么在这个线程从该方法返回之前,其他所有要调用类中任何标记synchronized方法的线程都会被阻塞。
2.synchronized原理
在Java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁依赖对象而存在。当我们调用某个对象的synchronized修饰的方法时,就获取了该对象的同步锁。例如synchronized(obj)方法就获取了obj这个对象的同步锁。不同线程对同步锁的访问是互斥的。也就是说,在某一个时刻,对象的同步锁只能被一个线程获取到!其他要获取该锁的线程都会被阻塞。知道线程释放了该锁,其他线程才能去获取同步锁,然后执行代码块。详细的synchronized工作原理请见博客:synchronized实现原理
3.synchronized基本用法
synchronized语句计算一个对象引用,试图对该对象完成锁操作,并且在完成所操作前停止处理。当锁操作完成,synchronized语句体得到执行。当语句体执行完毕(无论正常与否),解锁操作自动执行。synchronized经常与方法连用。public synchronized void function(){ //保护函数 }
一种比较好的办法是,如果某个变量由一个线程赋值,并由别的线程引用或赋值,那么所有对该变量的访问都必须在某个synchronized语句或者synchronized方法内,
synchronized(this){ //保护代码块 }
有了synchronized关键字,多线程程序的运行结果将变得可以控制。synchronized关键字用于保护共享数据。所以编程时分清共享数据很重要。
4.synchronized代码演示
4.1 synchronized为对象实例加锁
class MyRunable implements Runnable { @Override public void run() { synchronized(this) { try { for (int i = 0; i < 5; i++) { Thread.sleep(100); // 休眠100ms System.out.println(Thread.currentThread().getName() + " loop " + i); } } catch (InterruptedException ie) { } } } } public class Demo1_1 { public static void main(String[] args) { Runnable demo = new MyRunable(); Thread t1 = new Thread(demo, "t1"); Thread t2 = new Thread(demo, "t2"); t1.start(); t2.start(); } }
运行结果:
t1 loop 0 t1 loop 1 t1 loop 2 t1 loop 3 t1 loop 4 t2 loop 0 t2 loop 1 t2 loop 2 t2 loop 3 t2 loop 4
结果说明:
run()方法中存在synchronized(this)代码块,而且t1和t2都是基于Runnable对象创建的线程。这就意味着,我们可以将synchronized(this)中的this看作是Runnable对象;因此t1和t2共享demo对象的同步锁。所以,当一个线程运行的时候,另外一个线程必须等待“运行中的线程”释放同步锁之后才能运行。特此说明:synchronized(this)中的this是指当前的类对象,即synchronized(this)所在的类对应的当前对象。它的作用是获取“当前对象的同步锁”。
4.2 synchronized为方法加锁
synchronized方法是用synchronized修饰的方法,具体示例这里不给出了,有兴趣的童鞋,可以参照4.1给方法加上synchronized修饰。相关文章推荐
- Java多线程基础--04之 synchronized关键字
- java 多线程系列基础篇(四)之 synchronized关键字
- 【黑马程序员】03 Java基础之关键字(下)
- 多线程3:Java内置锁与synchronized关键字
- java基本教程之synchronized关键字 java多线程教程
- Java多线程系列03----synchronized
- 黑马程序员-JAVA学习之多线程和synchronized关键字
- 初学Java多线程:使用Synchronized关键字同步类方法
- 九、初学Java多线程:使用Synchronized关键字同步类方法
- 黑马程序员_Java基础03_多线程
- java多线程编程之使用Synchronized关键字同步类方法
- Java基础-synchronized关键字的用法
- Java多线程的例子及synchronized关键字锁定对象的用法
- Java多线程基础篇三------synchronized
- Java 多线程编程之三:synchronized 关键字的使用
- 初学Java多线程:使用Synchronized关键字同步类方法
- Java 多线程(六) synchronized关键字详解
- (转)初学Java多线程:使用Synchronized关键字同步类方法
- 【夯实基础】java关键字synchronized 详解
- Java 多线程 —— synchronized关键字