06 synchronized代码块

使用synchronizd声明的方法在某些情况下是由弊端的,比如A线程调用同步的方法执行一个很长时间的任务,那么B线程就必须等待比较长的时间才能执行,这样的情况下可以使用synchronized代码块去优化代码执行时间,也就是通常所说的减小锁的粒度。

 

synchronized可以使用任意的Object进行加锁,用法比较灵活:

package edu.sdut.thread01;

 

/**

 * 使用synchronized代码块加锁,比较灵活

 * @author Vision_TXG

 *

 */

public class MyThread07 {

public void method1() {

synchronized(this) { //对象锁

try {

System.out.println("do method1..");

Thread.sleep(2000);

}catch(Exception e) {

e.printStackTrace();

}

}

}

public void method2() {//类锁

synchronized (MyThread07.class) {

try {

System.out.println("do method2..");

Thread.sleep(2000);

}catch(Exception e) {

e.printStackTrace();

}

}

}

private Object lock = new Object();

public void method3() {//任何对象锁

synchronized (lock) {

try {

System.out.println("do method3..");

Thread.sleep(2000);

}catch(Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

final MyThread07 m = new MyThread07();

Thread t1 = new Thread(new Runnable() {

 

@Override

public void run() {

// TODO Auto-generated method stub

m.method1();

}

});

Thread t2 = new Thread(new Runnable() {

 

@Override

public void run() {

// TODO Auto-generated method stub

m.method2();

}

});

Thread t3 = new Thread(new Runnable() {

 

@Override

public void run() {

// TODO Auto-generated method stub

m.method3();

}

});

t1.start();

t2.start();

t3.start();

}

}

 

另外特别注意一个问题,就是不要使用String的常量进行加锁,会出现死循环问题:

package edu.sdut.thread01;

 

/**

 * synchronized代码块对字符串的锁,注意String常量的缓存功能

 * @author Vision_TXG

 *

 */

public class MyThread08 {

/**

 * 使用字符串常量的时候,因为只有一个引用,所以对常量进行加锁的时候,一个线程访问后,另一个线程无法访问

 * 相当于加一个类锁

 *

 * 而使用new String("")的话表示每个线程在执行的时候,加锁的时候是针对的不同的对象

 */

public void method() {

//new String("字符串常量")

synchronized(/*MyThread08.class*/new String("字符串常量")/*"字符串常量"*/) {

try {

while(true) {

System.out.println("当前线程 :" + Thread.currentThread().getName()+" 开始");

Thread.sleep(1000);

System.out.println("当前线程 :" + Thread.currentThread().getName()+" 结束 ");

}

}catch(Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

final MyThread08 m = new MyThread08();

Thread t1 = new Thread(new Runnable() {

 

@Override

public void run() {

// TODO Auto-generated method stub

m.method();

}

},"t1");

Thread t2 = new Thread(new Runnable() {

 

@Override

public void run() {

// TODO Auto-generated method stub

m.method();

}

},"t2");

t1.start();

t2.start();

}

}

 

 

 

镜对象的改变问题,当使用一个对象进行加锁的时候,要注意对象本身发生改变的时候,那么持有的锁就不同。如果对象本身不发生改变,那么依然是同步的,即使是对象的属性发生了改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值