Java线程(一):synchronized
来源:互联网 发布:淘宝运营需要学美工吗 编辑:程序博客网 时间:2024/05/22 06:27
一、什么时候会出现线程安全问题?
当多个线程同时访问一个资源(共享资源)时会出现线程安全。资源可以是一个变量、一个对象、一个文件、一个数据库表等。需要注意的是如果多个程序同时访问一个方法,定义在方法内部的局部变量并不是临界资源(共享资源),因为方法是在栈中执行的,而栈是线程私有的,因此不会出现线程安全问题。
二、如何解决线程安全问题?
通常来说在通过对访问共享资源代码加锁,当一个线程来访问时加锁,其他线程等待这个线程释放锁,当前线程执行完后加锁代码后释放锁资源。其他线程就可以访问共享资源了。在Java中,每一个对象都拥有一个锁标记(monitor),也称为监视器,多线程同时访问某个对象时,线程只有获取了该对象的锁才能访问。
Java提供了两种方式来实现同步互斥访问:synchronized和Lock。
三、synchronized同步代码块和同步方法代码示例
package sync;public class TestSynchronized {static TestSynchronized ts = new TestSynchronized();//所有线程共用这一个锁public static void main(String[] args) {new TestSynchronized().new Thread1().start();new TestSynchronized().new Thread2().start();}private void invoke() {try {synchronized (ts) {//同步代码块for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ":" + "写数据库" + i);Thread.sleep(100);}}} catch (InterruptedException e) {e.printStackTrace();}}class Thread1 extends Thread{public void run(){ts.invoke();}}class Thread2 extends Thread{public void run(){ts.invoke();}}}运行结果:Thread-0和Thread-1依次执行,没有出现相互竞争执行。
Thread-0:写数据库0
Thread-0:写数据库1
Thread-0:写数据库2
Thread-0:写数据库3
Thread-0:写数据库4
Thread-1:写数据库0
Thread-1:写数据库1
Thread-1:写数据库2
Thread-1:写数据库3
Thread-1:写数据库4
如果将锁加在方法上执行,结果依然一样:
private synchronized void invoke() {try {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ":" + "写数据库" + i);Thread.sleep(100);}} catch (InterruptedException e) {e.printStackTrace();}}运行结果:
Thread-0:写数据库0
Thread-0:写数据库1
Thread-0:写数据库2
Thread-0:写数据库3
Thread-0:写数据库4
Thread-1:写数据库0
Thread-1:写数据库1
Thread-1:写数据库2
Thread-1:写数据库3
Thread-1:写数据库4
四、同步方法和同步代码块的区别。
synchronized代码块使用起来比synchronized方法要灵活得多。因为也许一个方法中只有一部分代码只需要同步,如果此时对整个方法用synchronized进行同步,会影响程序执行效率。而使用synchronized代码块就可以避免这个问题,synchronized代码块可以实现只对需要同步的地方进行同步。
五、synchronized需要注意的几点。
1)当一个线程访问一个对象的synchronized方法func1其他线程不能访问这个对象方法func1,因为一个对象只有一个锁。只有释放了锁才能访问func1。
2)当一个线程访问一个对象的synchronized方法func1其他线程可以访问这个对象的非synchronized方法,因为其他方法不需要该对象的锁。
3)如果一个类有static synchronized方法f1和synchronized方法f2,当两个线程分别访问f1和f2时是不会发生互斥的问题,因为一个是对象锁一个是类锁,不是同一个锁。
4)如果synchronized方法或者synchronized代码块发生异常,是不会出现由于异常导致死锁,因为发生异常后JVM会释放锁,这个Lock不一样,lock需要手动释放锁。
- Java线程(一):synchronized
- Java synchronized同步线程机制(一)
- Java中的线程同步块synchronized实现一
- java多线程学习一线程安全之内存、synchronized、volatile
- java线程同步volatile与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编程实现文件编码转换
- C#基础(2)——字符操作
- 今年最新的30个Android库
- BurpSuite安全测试
- ANDROID样式的开发:LAYER-LIST篇
- Java线程(一):synchronized
- 修改hosts不必重启 立刻生效
- Task Scheduler
- AlphaGo Zero的伟大与局限—ResNet作者、旷视研究院院长孙剑深度评述
- 一文了解机器学习开发工具
- 掘金3000亿在线教育市场 ‖ 沪江英语、流利说、Master Learner如何用AI影响1400万教师和1.88亿学生
- 一些JAVA代码(单词长度)
- 安卓常用工具类-ToastUtils【提示工具类】
- dedecms相关文档调用方法