java并发编程之synchronized
来源:互联网 发布:淘宝客转换软件 编辑:程序博客网 时间:2024/05/16 00:40
1.多个线程访问同一资源时会产生线程安全问题,因此要实现同步互斥访问资源。
举例:在购票时,总票数10,售票员1卖一张票票数为9,但在售票员1卖这张票的过程中,售票员2也在卖票其开始读到总票数也为10,卖一张9,然后两个售票员都读到了余票为9的错误的信息。
2.解决线程安全问题方式:
(1)synchronized同步方法或同步块(2)lock锁
在java中,每个对象都有一个锁标记,当线程要访问被synchronized关键字修饰的代码片段时,必须检查该对象的锁是否可用,可用,获得锁,执行代码,释放锁。其他想访问该代码片段没获得该锁的线程就处于自我阻塞状态。
<1>synchronized 同步方法
未使用synchronized修饰:
package day03;import java.util.ArrayList;/** * @author wangpei * @version 创建时间:2017年2月10日 上午10:38:22 类说明 */public class Test implements Runnable { final InsertData insertData = new InsertData(); public void run() { insertData.insert(Thread.currentThread()); } public static void main(String[] args) { Test t = new Test(); new Thread(t, "Thread-0").start(); new Thread(t, "Thread-1").start(); }}class InsertData { private ArrayList<Integer> arrayList = new ArrayList<Integer>(); public void insert(Thread thread) { for (int i = 0; i < 5; i++) { System.out.println(thread.getName() + "在插入数据" + i); arrayList.add(i); } }}
执行结果:
Thread-0在插入数据0Thread-1在插入数据0Thread-1在插入数据1Thread-0在插入数据1Thread-1在插入数据2Thread-0在插入数据2Thread-1在插入数据3Thread-0在插入数据3Thread-1在插入数据4Thread-0在插入数据4
线程0和线程1的执行是无序的
使用synchronized:
class InsertData { private ArrayList<Integer> arrayList = new ArrayList<Integer>(); public synchronized void insert(Thread thread) { for (int i = 0; i < 5; i++) { System.out.println(thread.getName() + "在插入数据" + i); arrayList.add(i); } }}
执行结果:
Thread-0在插入数据0Thread-0在插入数据1Thread-0在插入数据2Thread-0在插入数据3Thread-0在插入数据4Thread-1在插入数据0Thread-1在插入数据1Thread-1在插入数据2Thread-1在插入数据3Thread-1在插入数据4
Thread-0先获得对象的锁然后,执行代码插入数据,然后释放锁,接着Thread-1执行。0,1线程是顺序执行的。
注意:
(1)在并发访问时,要将资源域设置为private,防止其它线程直接操作该资源。
(2)当一个线程在访问该对象的synchronized修饰的方法时,其它线程可以访问该对象的非synchronized修饰的方法,但不可以访问该对象的其他被synchronized修饰的方法。(对象锁只有一个,已经在使用中,必须获得锁在可以访问synchronized修饰的方法)
例子:
对于对象object:有方法
synchronized void s1(){},
synchronized void s2(){},
void s3(){},
当线程Thread-0获得锁而操作s1方法时,线程Thread-1可以访问s3方法,不可以访问s2方法。
<2>synchronized 同步代码块
形式:
synchronized(对象this(当前对象)/属性){}
class InsertData { private ArrayList<Integer> arrayList = new ArrayList<Integer>(); public void insert(Thread thread) { synchronized(arrayList){ for (int i = 0; i < 5; i++) { System.out.println(thread.getName() + "在插入数据" + i); arrayList.add(i); } } }}
同步代码块,比同步方法范围小,在执行时访问线程Thread-0访问a方法中同步代码块中的内容,而没获得锁的Thread-1仍旧可访问a方法中的非synchronized代码快。
<3>类锁
针对每个类,也有一个锁(作为class对象的一部分)。synchronized static修饰的方法可以在类范围内防止对static数据的并发访问。
- java并发编程之synchronized
- java并发编程之synchronized
- java 并发编程之synchronized。
- Java并发编程之synchronized
- Java并发编程之synchronized
- Java并发编程之synchronized
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- java 并发编程(一)之synchronized
- java 并发编程(二)之synchronized实例
- java 并发编程(三)之synchronized
- Java 进阶 之 并发编程 Synchronized
- 【Java并发编程】之synchronized和Lock
- Java复习-并发编程之synchronized
- Java 多线程并发编程之 Synchronized 关键字
- Ubuntu忘记密码
- 动规-多重背包
- android中java和js交互
- python写爬虫3-MongoDB数据缓存(采集58出租房信息)
- 分布式锁
- java并发编程之synchronized
- ExceptionUtil
- Spring4.3.x 容器中bean的创建过程(5)—— 注册bean的销毁方法
- 【小工具】一个简单实用的jQuery手风琴
- FtpUtil
- Netty示例:文件下载
- 动规-01背包
- HttpClientUtil
- 神经网络绘画示例