标签:tar out 遇到 color 资源 class name his ring
synchroized是jvm提供的,无需手动控制它可以自动对多线程访问的资源进行加锁与解锁,它可以修饰方法,也可以修饰代码块.
这边博客记录下个人对synchrozied的理解如下:
1.为什么Java要提供synchronized?
当多条线程去对一个类的实例变量进行修改,这时会发生变量的不确定性.为解决这个问题,使用synchronized修饰,使得在某一时刻,只能有一条线程进行操作.实现的方式是加锁与解锁.
2.实例演示多线程访问共享变量产生的问题.
public class ManyThreadModify implements Runnable{
private int value = 10;
@Override
public void run() {
for(int i = 0; i < 10; i++) {
value--;
System.out.println(Thread.currentThread().getName() + "修改value的值为:" + value);
}
}
public static void main(String[] args) {
ManyThreadModify mm = new ManyThreadModify();
//使用实现Runnable接口的方式可以共享变量,每启动的线程都是以target形式启动的
new Thread(mm , "线程01").start();
new Thread(mm , "线程02").start();
}
}
可以看到,出现了value的值两次等于8的情况,这就是线程不安全造成的,在run方法上加上synchronize修饰可以解决这个问题.
3.synchrozied修饰方法和修饰代码块的区别
修饰方法:synchronize public void test(){}
修饰代码块:synchronize(锁对象){ //代码块 }
区别:
public class SynchronizedMethodAndCode{ //synchronize修饰方法 public synchronized void test01() { try { System.out.println("this is method test01..."); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } public void test02() { //synchronize修饰代码块,锁对象为当前对象 synchronized (this) { System.out.println("this is method test02..."); } } public void test03() { String str = "s"; //synchronize修饰代码块,锁对象为str synchronized (str) { System.out.println("this is method test03..."); } } }
启动线程访问
public class SynchroziedMain { public static void main(String[] args) { SynchronizedMethodAndCode sc = new SynchronizedMethodAndCode(); //启动线程1访问test01方法 new Thread(new Runnable() { @Override public void run() { sc.test01(); } }).start(); //启动线程2访问test02方法 new Thread(new Runnable() { @Override public void run() { sc.test02(); } }).start(); //启动线程3访问test03方法 new Thread(new Runnable() { @Override public void run() { sc.test03(); } }).start(); } }
可以看到打印结果,
分析:启动线程1访问test01方法时遇到sleep(3000),线程1没有释放锁资源,在这里,锁资源就是当前对象,锁被线程1拿在了手里没有释放,而test02方法的锁对象this也是当前对象,所以线程1和线程2使用的是同一把锁,线程2等待线程1 sleep()结束才能获得锁,进入test02方法的打印代码中,所以线程3先打印了,因为它的锁是自己定义的一个String对象.
总结:synchronize修饰方法的锁对象只能是this当前对象
synchronize修饰代码块可以修改锁对象
synchrozied方法和synchrozied修饰代码块的区别
标签:tar out 遇到 color 资源 class name his ring
原文地址:https://www.cnblogs.com/yuchangying/p/9364607.html