synchronized 方法与锁对象
来源:互联网 发布:tensorflow vgg 编辑:程序博客网 时间:2024/05/17 08:33
两个线程均调用共享对象的同步方法:
class MyObject{ public synchronized void methodA(){ System.out.println("begin methodA threadName= " + Thread.currentThread().getName()); try { Thread.sleep(5000); System.out.println("methodA end"); } catch (InterruptedException e) { e.printStackTrace(); } }}class ThreadA extends Thread{ private MyObject object; public ThreadA(MyObject object){ this.object = object; } @Override public void run() { object.methodA(); }}class ThreadB extends Thread{ private MyObject object; public ThreadB(MyObject object){ this.object = object; } @Override public void run() { object.methodA(); }}public class Run { public static void main(String[] args) { MyObject object = new MyObject(); ThreadA a = new ThreadA(object); a.setName("A"); ThreadB b = new ThreadB(object); b.setName("B"); a.start(); b.start(); }}
结果肯定是顺序执行:
begin methodA threadName= AmethodA endbegin methodA threadName= BmethodA end
A线程调用共享对象的同步方法,B线程调用共享对象非同步方法:
class MyObject{ public synchronized void methodA(){ System.out.println("begin methodA threadName= " + Thread.currentThread().getName()); try { Thread.sleep(5000); System.out.println("methodA end"); } catch (InterruptedException e) { e.printStackTrace(); } } public void methodB(){ System.out.println("begin methodB threadName= " + Thread.currentThread().getName()); try { Thread.sleep(5000); System.out.println("methodB end"); } catch (InterruptedException e) { e.printStackTrace(); } }}class ThreadA extends Thread{ private MyObject object; public ThreadA(MyObject object){ this.object = object; } @Override public void run() { object.methodA(); }}class ThreadB extends Thread{ private MyObject object; public ThreadB(MyObject object){ this.object = object; } @Override public void run() { object.methodB(); }}public class Run { public static void main(String[] args) { MyObject object = new MyObject(); ThreadA a = new ThreadA(object); a.setName("A"); ThreadB b = new ThreadB(object); b.setName("B"); a.start(); b.start(); }}
结果是:
begin methodA threadName= Abegin methodB threadName= BmethodA endmethodB end
A线程调用共享对象的同步方法,B线程调用共享对象另一个同步方法
class MyObject{ public synchronized void methodA(){ System.out.println("begin methodA threadName= " + Thread.currentThread().getName()); try { Thread.sleep(5000); System.out.println("methodA end"); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodB(){ System.out.println("begin methodB threadName= " + Thread.currentThread().getName()); try { Thread.sleep(5000); System.out.println("methodB end"); } catch (InterruptedException e) { e.printStackTrace(); } }}class ThreadA extends Thread{ private MyObject object; public ThreadA(MyObject object){ this.object = object; } @Override public void run() { object.methodA(); }}class ThreadB extends Thread{ private MyObject object; public ThreadB(MyObject object){ this.object = object; } @Override public void run() { object.methodB(); }}public class Run { public static void main(String[] args) { MyObject object = new MyObject(); ThreadA a = new ThreadA(object); a.setName("A"); ThreadB b = new ThreadB(object); b.setName("B"); a.start(); b.start(); }}
结果是:
begin methodA threadName= AmethodA endbegin methodB threadName= BmethodB end
结论:
1. A线程和B线程均调用object对象的synchronized方法,则必须是同步方式调用
2. A线程先持有object对象的Lock锁,B线程可以以异步方式调用object对象中的非synchronized类型的方法
3. A线程先持有object对象的Lock锁,B线程如果此时调用object对象中的synchronized类型的方法则需等待,即只能是同步方式调用
结论2即对应了脏读的现象:
比如赋值方法是同步,取值方法是非同步,则可能出现脏读,即在读取实例变量时,此值已经被其他线程更改过了
class MyObject{ private String username = "A"; private String password = "AA"; public synchronized void setValue(String username, String password){ this.username = username; try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } this.password = password; System.out.println("setValue username : " + username + " password : " + password); } public void getValue(){ System.out.println("getValue username : " + username + " password : " + password); }}class ThreadA extends Thread{ private MyObject object; public ThreadA(MyObject object){ this.object = object; } @Override public void run() { object.setValue("B", "BB"); }}public class Run { public static void main(String[] args) { MyObject object = new MyObject(); ThreadA a = new ThreadA(object); a.setName("A"); a.start(); try { Thread.sleep(200);//结果受此值影响 } catch (InterruptedException e) { e.printStackTrace(); } object.getValue(); }}
可对getValue添加synchronzied关键字修饰,避免脏读
当线程调用anyObject对象加入synchronized关键字修饰的X方法时,A线程就获得了X方法锁,更准确的讲是获得了anyObject对象的锁,所以其他线程必须等A线程执行完毕才可以调用X方法,但是其他线程可以调用anyObject的其他非synchronized关键字修饰的方法。可若其他线程调用anyOjbect的其他synchronized关键字修饰的方法时,也必须等待A线程执行完毕,释放了对象锁后才可以调用
0 0
- synchronized 方法与锁对象
- synchronized&synchronized(something)与对象锁
- synchronized&synchronized(something)与对象锁
- synchronized关键字与对象锁
- synchronized关键字与对象锁
- synchronized锁方法,synchronized锁对象,synchronized(this),synchronized(class)最佳理解方式
- Java synchronized与Lock对象锁
- synchronized关键字修饰对象锁,同步与非同步对该方法的访问及修改
- static synchronized方法与synchronized class是不是一把锁
- synchronized,当作用于方法与对象的不同之处
- java synchronized对象锁与类锁的区别、同步代码块与同步方法的区别
- 静态synchronized方法和非静态synchronized方法的锁对象不是同一个
- java synchronized 方法 对象 区别
- synchronized 静态 非静态 方法 使用不同锁对象
- java多线程----synchronized方法锁能否锁住对象呢?
- 线程锁synchronized (this)锁住的是对象还是方法
- 理解synchronized对象锁
- 对象锁synchronized
- js惰性载入-性能-滚轮事件
- git创建项目并上传代码
- Spring AOP原理解释
- Blcoking I/O & NonBlocking I/O
- la4327 优先队列优化dp
- synchronized 方法与锁对象
- 服务器集群监控 Ganglia 搭建 CenOS6.5
- 如何用AWS(亚马逊云服务器)搭建一个自己的BLOG (1) – 申请一个AWS云服务器
- hdu 4602 Partition
- 项目4:换硬币
- redis常见的几种使用场景
- 本地音乐播放器(三)——播放界面和服务的通信
- phpmyadmin使用空密码登入配置方法
- 继承案例