java方法synchronized_java中synchronized几种使用方法

在使用synchronized方法时,我总结了使用的情形:

第一种情形:

/**

* Created by zhangzheming on 2018/1/12.

*/

public class SyncDubbo1 {

public synchronized void method1(){

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

method2();

}

public synchronized void method2() {

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

method3();

}

public synchronized void method3() {

System.out.println("method3");

}

public static void main(String[] args){

final SyncDubbo1 sd = new SyncDubbo1();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

sd.method1();

}

});

t1.start();

}

}

965543e23bdc

运行结果

从上面的运行结果可以看出:在嵌套方法中使用synchronized,多线程情况下是线程安全的。

第二种情况:

/**

* Created by zhangzheming on 2018/1/12.

*/

public class syncDubbo2 {

// 主类

static class Main{

public int i = 10;

public synchronized void operationSup(){

try {

i--;

System.out.println("Main print i= "+i);

Thread.sleep(100);

}catch (Exception e){

e.printStackTrace();

}

}

}

// 子类

static class Sub extends Main{

public synchronized void operationSub(){

try{

while (i>0){

i--;

System.out.println("Sub print i= "+i);

Thread.sleep(100);

this.operationSup();

}

}catch (Exception e){

e.printStackTrace();

}

}

}

public static void main(String[] args){

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

Sub sub = new Sub();

sub.operationSub();

}

});

t1.start();

}

}

965543e23bdc

运行结果

此种情形主要是说明两点:

(1)在出现父子类继承关系的情况下,父类的成员变量也可以被子类继承。

(2)在父类和子类都使用synchronized ,出现多线程情况下,是线程安全的。

synchronized 的使用出现异常情况下,如果遇到异常,我们也需要处理异常情况,请看下面的代码:

/**

* Created by zhangzheming on 2018/1/12.

*/

public class SyncException {

private int i = 0;

public synchronized void operation(){

while (true){

try{

i++;

Thread.sleep(200);

System.out.println(Thread.currentThread().getName()+", i=" + i);

if (i%10 == 0){

Integer.parseInt("a");

}

}catch (InterruptedException e){

e.printStackTrace();

// (3) contiune;

//(2)System.out.println("log info i = "+i);

//(1)throw new RuntimeException();

}

}

}

public static void main(String[] args){

final SyncException se = new SyncException();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

se.operation();

}

},"t1");

t1.start();

}

}

这段代码其实将输出变量i的累加值,但是每逢遇到被10整除的数时,就会遇到异常现象,这种情况下,我们有三种解决办法:

(1)第一种办法:throw new RuntimeException(); 将运行异常抛出,这样程序就会停止下来,不会影响到后面的任务,比较适合任务之前有先后顺序的关联关系;

(2)第二种办法:System.out.println("log info i = "+i);将错误信息打印出来或者打印到日志中出,事后进行分析和修复。

(3)第三种办法:contiune; 那就是最坏的情况,忽略错误,不处理异常情况

不要使用String字符串加锁,这样会导致死循环产生

请看下面的例子:

package Thread;

/**

* Created by zhangzheming on 2018/1/15.

*/

public class StringLock {

public void method(){

// 使用字符串当做对象

synchronized ("字符串常量"){

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 StringLock stringLock = new StringLock();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

stringLock.method();

}

});

Thread t2 = new Thread(new Runnable() {

@Override

public void run() {

stringLock.method();

}

});

t1.start();

t2.start();

}

}

965543e23bdc

运行结果

按照我们预想的,启动两个线程会在执行结果中产生两个线程交替进行,但是与实际结果不相同,这是为什么?

原因在于字符串属于引用类型,不管什么样的字符串都是一个类型对象,这样就导致了只有一个线程存在,回头想想其实要解决这个问题,就是满足synchronized 锁住的是对象就可以了,修改如下:

package Thread;

/**

* Created by zhangzheming on 2018/1/15.

*/

public class StringLock {

public void method(){

// 使用字符串当做对象

synchronized (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 StringLock stringLock = new StringLock();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

stringLock.method();

}

});

Thread t2 = new Thread(new Runnable() {

@Override

public void run() {

stringLock.method();

}

});

t1.start();

t2.start();

}

}

965543e23bdc

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值