java多线程的同步
❶ java 实现线程同步的方式有哪些
实现同步机制有两个方法:
1、同步代码块:
synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。
2、同步方法:
public synchronized 数据返回类型 方法名(){}
就是使用 synchronized 来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是 this 也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。
实现同步机制注意以下几点: 安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
1,不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源方法的进行同步。
2,如果可变类有两种运行环境,当线程环境和多线程环境则应该为该可变类提供两种版本:线程安全版本和线程不安全版本(没有同步方法和同步块)。在单线程中环境中,使用线程不安全版本以保证性能,在多线程中使用线程安全版本.
❷ java中线程同步的几种方法
java中多线程的实现方法有两种:1.直接继承thread类;2.实现runnable接口;同步的实现方法有五种:1.同步方法;2.同步代码块;3.使用特殊域变量(volatile)实现线程同步;4.使用重入锁实现线程同步;5.使用局部变量实现线程同步 。
其中多线程实现过程中需注意重写或者覆盖run()方法,而对于同步的实现方法中使用较常使用的是利用synchronized编写同步方法和代码块。
❸ java多线程中synchronized关键字的用法
由于同一进程内的多个线程共享内存空间 在Java中 就是共享实例 当多个线程试图同时修改某个实例的内容时 就会造成冲突 因此 线程必须实现共享互斥 使多线程同步
最简单的同步是将一个方法标记为synchronized 对同一个实例来说 任一时刻只能有一个synchronized方法在执行 当一个方法正在执行某个synchronized方法时 其他线程如果想要执行这个实例的任意一个synchronized方法 都必须等待当前执行 synchronized方法的线程退出此方法后 才能依次执行
但是 非synchronized方法不受影响 不管当前有没有执行synchronized方法 非synchronized方法都可以被多个线程同时执行
此外 必须注意 只有同一实例的synchronized方法同一时间只能被一个线程执行 不同实例的synchronized方法是可以并发的 例如 class A定义了synchronized方法sync() 则不同实例a sync()和a sync()可以同时由两个线程来执行
多线程同步的实现最终依赖锁机制 我们可以想象某一共享资源是一间屋子 每个人都是一个线程 当A希望进入房间时 他必须获得门锁 一旦A获得门锁 他进去后就立刻将门锁上 于是B C D就不得不在门外等待 直到A释放锁出来后 B C D中的某一人抢到了该锁(具体抢法依赖于 JVM的实现 可以先到先得 也可以随机挑选) 然后进屋又将门锁上 这样 任一时刻最多有一人在屋内(使用共享资源)
Java语言规范内置了对多线程的支持 对于Java程序来说 每一个对象实例都有一把 锁 一旦某个线程获得了该锁 别的线程如果希望获得该锁 只能等待这个线程释放锁之后 获得锁的方法只有一个 就是synchronized关键字 例如
public class SharedResource {
private int count = ;
public int getCount() { return count; }
public synchronized void setCount(int count) { unt = count; }
}
同步方法public synchronized void setCount(int count) { unt = count; } 事实上相当于
public void setCount(int count) {
synchronized(this) { // 在此获得this锁
unt = count;
} // 在此释放this锁
}
红色部分表示需要同步的代码段 该区域为 危险区域 如果两个以上的线程同时执行 会引发冲突 因此 要更改SharedResource的内部状态 必须先获得SharedResource实例的锁
退出synchronized块时 线程拥有的锁自动释放 于是 别的线程又可以获取该锁了
为了提高性能 不一定要锁定this 例如 SharedResource有两个独立变化的变量
public class SharedResouce {
private int a = ;
private int b = ;
public synchronized void setA(int a) { this a = a; }
public synchronized void setB(int b) { this b = b; }
}
若同步整个方法 则setA()的时候无法setB() setB()时无法setA() 为了提高性能 可以使用不同对象的锁
public class SharedResouce {
private int a = ;
private int b = ;
private Object sync_a = new Object()
private Object sync_b = new Object()
public void setA(int a) {
synchronized(sync_a) {
this a = a;
}
}
public synchronized void setB(int b) {
synchronized(sync_b) {
this b = b;
}
lishixin/Article/program/Java/gj/201311/27512
❹ java多线程开发的同步机制有哪些
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁); 如果这个时候同步对象的锁被其他线程拿走了,他(这个线程)就只能等了(线程阻塞在锁池 等待队列中)。 取到锁后,他就开始执行同步代码(被synchronized修饰的代码);线程执行完同步代码后马上就把锁还给同步对象,其他在锁池中 等待的某个线程就可以拿到锁执行同步代码了。这样就保证了同步代码在统一时刻只有一个线程在执行。
众所周知,在Java多线程编程中,一个非常重要的方面就是线程的同步问题。
关于线程的同步,一般有以下解决方法:
1. 在需要同步的方法的方法签名中加入synchronized关键字。
2. 使用synchronized块对需要进行同步的代码段进行同步。
3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。
另外,为了解决多个线程对同一变量进行访问时可能发生的安全性问题,我们不仅可以采用同步机制,更可以通过JDK 1.2中加入的ThreadLocal来保证更好的并发性。