java synchronized 同一对象多实例线程安全

synchronized java 语言最简单的线程并发同步语法,上源码最快理解,

Resouce类表示并发资源

使用方法1.直接锁住某一个变量,如代码中的lock,注意这里lock必须为static的。如果不是static有什么后果?

public class Resource {

private static Object lock = new Object();

private Object unLock = new Object();

public void say() {

synchronized (unLock) {

System.out.println("come in unlock");

synchronized (lock) {

System.out.println("come in sleep");

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

方法2,在方法前加上synchroized关键字

public synchronized  void say() {

System.out.println("come in sleep");

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

方法3,锁住class类

package com.learn.bao.mutithread;

public class Resource {

public void say() {

synchronized (Resource.class) {

System.out.println("come in unlock");

System.out.println("come in sleep");

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

现在依次说一下其中的原理。

使用synchroized方法前要明白,这个关键字它到底锁住的是什么资源。

在多线程中,如果Resouce对象只有一个,上面几种方法都是可以的。

比如 下面的代码,都是可以的

package com.learn.bao.mutithread;

public class TestThread extends Thread {

private Resource r;

public TestThread(Resource r) {

this.r = r;

}

@Override

public void run() {

r.say();

}

}

package com.learn.bao.mutithread;

public class Main {

public static void main(String[] args) {

Resource r = new Resource();

for (int i = 0; i < 3; i++) {

TestThread t = new TestThread(r);

t.start();

}

}

}

为什么可以,因为所有线程都共用了一个对象Resouce,只有一个实例,所以加上synchroized关键词一定是线程安全的。

但是下面情况怎么办?

package com.learn.bao.mutithread;

public class Main {

public static void main(String[] args) {

for (int i = 0; i < 3; i++) {

Resource r = new Resource();

TestThread t = new TestThread(r);

t.start();

}

}

}

对于方法1来说如果lock不是静态变量就不能在线程中共享,所以也就无法实现线程安全,所以锁变量必须加上static关键字。

对于方法2由于锁的是Resource是对象本身,如果Resource有多个对象,自然无法实现线程安全,只能保证在同一个对象上是线程安全的,对于上面的情况就无法适用了。如果是多实例就需要手动加锁或者把方法改成静态。

方法3对于多实例和单实例而言都是安全的,因为它锁住的是class对象,在多线程中只有一份唯一的对象,所以是安全的,同static lock,这个也是我推荐的做法,代码比较简洁。

这里还要强调一下static synchroized静态同步方法它实际锁住的是Resouce这个类,这个类与他有多个实例无关,即使是new Resource().say(),强制创建新对象调用静态同步方法也还是线程安全的。

时间: 2024-10-08 22:47:59

java synchronized 同一对象多实例线程安全的相关文章

【转】线程同步------java synchronized详解

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块.

Java多线程之简单的线程同步实例

数据类: package Thread.MyCommon; public class Data { public int num = 0; public synchronized int getEven() { ++num; Thread.yield();//让另外线程先执行,加大测试效果几率 ++num; return num; } } 线程类: package Thread.MyCommon; public class myThread implements Runnable { priva

java中volatile不能保证线程安全(实例讲解)

java中volatile不能保证线程安全(实例讲解) 转载  2017-09-04   作者:Think-007    我要评论 下面小编就为大家带来一篇java中volatile不能保证线程安全(实例讲解).小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 今天打了打代码研究了一下java的volatile关键字到底能不能保证线程安全,经过实践,volatile是不能保证线程安全的,它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而不是从缓存

Java synchronized详解

Java synchronized详解 第一篇: 使用synchronized 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--synchronized,这也大大简化了Java中多线程同步的使用.我们首先编写一个非常简单的多线程的程序,是模拟银行中的多个线程同时对同一个储蓄账户进行存款.取款操作的. 在程序中我们使用了一个简化版本的Account类,代表了一个银行账户的信息.在主程序中我们首先生成了1000个线程,然后启动它们

java synchronized使用

java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为锁语句产生一种互斥排斥的效果,这种机制常常被称为互斥机制. 线程是簇拥在共享资源门前,并不是排队进入,可以通过yield()和setPriority()来给线程调度提供建议,但这些建议未必会有多大的效果.这取决与你的具体平台和vm的实现:)--//from <think in java> java

Java synchronized 详解

下面的文字均来自其它博客和网页. 参考:http://www.jianshu.com/p/ea9a482ece5f 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问.需要明确的几个问题: synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.如果 再细的分类,synchronized可作用于instance变量.o

synchronized关键字以及实例锁 类锁

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块.

[zt]java synchronized详解

作者:GangWang 出处:http://www.cnblogs.com/GnagWang/ 记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个synchronized(t

java synchronized详解(原文基础改进)

记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(thi