synchnorized关键字

Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作用主要有三个:


能够保证同一时刻只有一个线程执行该段代码,保证程序的并发安全性

(1)确保线程互斥的访问同步代码
(2)保证共享变量的修改能够及时可见
(3)有效解决重排序问题。

问题,如果两个线程同时count++,最后结果比预计的少

public class SynchronizedTest implements Runnable {
	
	public static int count=0;
	static SynchronizedTest instance01=new SynchronizedTest(); 
	public static void main(String[] args) throws InterruptedException {
		Thread thread01=new Thread(instance01);
		Thread thread02=new Thread(instance01);
		thread01.start();
		thread02.start();
		thread01.join();
		thread02.join();
		System.out.println("wwqwq"+count);
	}
	@Override
	public void run() {
	  for(int i=0;i<2000;i++){
		count++;
	  }
	}

}

结果是

并不是20000

原因

 (1)读取count

 (2)将count 加一

 (3) 写入内存


Synchronized 锁分为
一、 对象锁
    (1)Synchronized 代码块

 public class SynchronizedTest implements Runnable {
	   public static void main(String[] args) {
		SynchronizedTest instance=new SynchronizedTest(); 
		Thread thread01=new Thread(instance);
		Thread thread02=new Thread(instance);
		thread01.start();
		thread02.start();
	}
	@Override
	public void run() {
		try {
			Thread.sleep(3000);
			synchronized (this) {
				System.out.println("我是线程"+Thread.currentThread().getName()+"开始执行");
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("我是线程"+Thread.currentThread().getName()+"执行结束");
	}
}

 

(2)Synchronized 修饰的普通方法

public class SynchronizedTest implements Runnable {
	public static void main(String[] args) {
		SynchronizedTest instance=new SynchronizedTest(); 
		Thread thread01=new Thread(instance);
		Thread thread02=new Thread(instance);
		thread01.start();
		thread02.start();
	}
	@Override
	public void run() {
		try {
			Thread.sleep(3000);
			method();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("我是线程"+Thread.currentThread().getName()+"执行结束");
	}
	
	public  synchronized void  method(){
		System.out.println("我是线程"+Thread.currentThread().getName()+"开始执行");
	}
}

 

二 、类锁
    (1)Synchronized 指定对象

	public class SynchronizedTest implements Runnable {
	public static void main(String[] args) {
		SynchronizedTest instance01=new SynchronizedTest(); 
		SynchronizedTest instance02=new SynchronizedTest(); 
		Thread thread01=new Thread(instance01);
		Thread thread02=new Thread(instance02);
		thread01.start();
		thread02.start();
	}
	@Override
	public void run() {
		try {
			Thread.sleep(3000);
			synchronized (SynchronizedTest.class) {
				System.out.println("我是线程"+Thread.currentThread().getName()+"开始执行");

			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("我是线程"+Thread.currentThread().getName()+"执行结束");
	}

}

 

    
    (2)Synchronized 修饰的静态方法

public class SynchronizedTest implements Runnable {
	public static void main(String[] args) {
		SynchronizedTest instance01=new SynchronizedTest(); 
		SynchronizedTest instance02=new SynchronizedTest(); 
		Thread thread01=new Thread(instance01);
		Thread thread02=new Thread(instance02);
		thread01.start();
		thread02.start();
	}
	@Override
	public void run() {
		try {
			Thread.sleep(3000);
			synchronized (SynchronizedTest.class) {
				System.out.println("我是线程"+Thread.currentThread().getName()+"开始执行");

			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("我是线程"+Thread.currentThread().getName()+"执行结束");
	}

}

 

缺点
    效率低:锁的释放情况少,试图获得锁时不能设定超时,不能中断一个正在试图获得锁的线程
    不够灵活:加锁和释放错时机单一,有单一条件的(某个对象),可能是不够的
    无法是否成功获取到锁

总结 
    1,一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待
    2,每个实例都有对应有自己的一把锁,不同的实例之间互不影响;例外
    锁对象是*.class以及synchronized修饰的是static方法的时候,所有对象共用同一把锁
    3,无论是方法正常执行完毕或者方法抛出的异常,都会释放锁
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值