java 多线程

synchronized关键字

方法或代码块的互斥性来完成实际上的一个原子操作。(方法或代码块在被一个线程调用时,其他线程处于等待状态)

所有的Java对象都有一个与synchronzied关联的监视器对象(monitor),允许线程在该监视器对象上进行加锁和解锁操作。

a、静态方法:Java类对应的Class类的对象所关联的监视器对象。

b、实例方法:当前对象实例所关联的监视器对象。

c、代码块:代码块声明中的对象所关联的监视器对象。

 

所以多线程操作同一个内容并要保持一致性时,就将该对象设为类的静态成员

public class syncTest {

	public static int count = 0;
	
	public static synchronized void addC(){
		if(count <100){
			count ++;		
			System.out.println(Thread.currentThread().getName() +"   "+count);			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
		
	public static void main(String args[]){
		Thread thread1 = new Thread();
		thread1 = new Thread(new Runnable(){
			public void run(){
				System.out.println("thread1 start run");
				while(count <100){
					syncTest.addC();
					
				}
			}
		});
		syncTest st = new syncTest();
		Thread thread2 = new Thread();
		thread2 = new Thread(new Runnable(){
			public void run(){
				System.out.println("thread2 start run");
				while(count <100){
					st.addC();
				}	
			}
		});
		thread1.start();
		thread2.start();
	}
}

  输出:

可以看到,两个线程操作的是同一个数

 LOCK:

synchronized的缺陷:

当一个线程获取了锁并执行该代码,其他线程便只能一直等待,等待该线程释放锁。而释放锁有两种情况:

  1. 获取锁的线程执行完了该代码块
  2. 线程执行发生异常,此时JVM会让线程自动释放锁

 

locksynchronized的区别:

  1. Lock不是Java语言内置的,synchronized的是Java的关键字,是内置特性。Lock是一个类,通过这个类可以实现同步访问。
  2. Locksynchronized有一点非常大的不同,采用synchronized不需要用户手动释放锁,当synchronized方法或者synchronized代码块执行完后,系统会自动让新县城释放对锁的占用。而lock必须要用户去手动释放。

 

获取lock的方式: lock(), trylock(), trylock(long time, timeout unit) lockInterrutibly()

对锁操作使用try{}catch{},释放的操作放在finnally{}

 

Lock lock = …

Lock.lock()

Try{

}catch(Exception e){

}

Finnally{

Lock.unlock();

}

 

Lock.lock()获取锁

 

Lock.tryLock()尝试获取锁,如果成功则返回true,失败则返回false

 

Lock.tryLock(long time, TimeUnit unit) 拿不到锁会等待一段时间,如果期限内拿不到则返回false

 

Lock.lockInterruptibly()

当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态。也就使说,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。

由于lockInterruptibly()的声明中抛出了异常,所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException。

 

posted on 2015-07-12 22:24  zxahu  阅读(161)  评论(0)    收藏  举报

导航