您的位置:首页 > 业界新闻

互联网并发编程之一 线程安全02

2017-12-03 15:14 225 查看
多个线程就有多把锁,每个线程都可以拿到自己指定的锁,分别获得锁之后在执行相应的syncronized的方法。

syncronized拿到的锁都是对象锁,锁住的是对象,而不是一段代码。

        示例

       

package com.jc.thread;

public class Thread02 {

public  int num = 0;

public synchronized  void printNum(String tag){

if(tag.equals("a")){

num = 1000;
System.out.println("tag a set num");
}else{
num = 2000;
System.out.println("tag b set num");
}
System.out.println("tag is "+ tag +"num is" + num);
}

public static void main(String[] args) {

final Thread02 thread01 = new Thread02();
final Thread02 thread02 = new Thread02();

//分別拿到的是两个对象的锁
Thread t = new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
thread01.printNum("a");
}
}, "thread1");

Thread t1 = new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
thread02.printNum("b");
}
}, "thread2");
t.start();
t1.start();

}

}


打印结果如下:

tag a set num

tag b set num

tag is b num is 2000

tag is a num is 1000

并不是我们预期的结果,这个是由于,线程活得的对象锁是不同的,所以相互之间执行并不受影响,如果需要多个线程访问对象的,拿到的是同一把对象的锁,则需要在方法中加上static 关键字

public  static int num = 0;

public  synchronized static void printNum(String tag){

if(tag.equals("a")){

num += 1000;
System.out.println("tag a set num");
}else{
num += 2000;
System.out.println("tag b set num");
}
System.out.println("tag is "+ tag +" num is " + num);
}


打印结果如下:

tag b set num

tag is b num is 2000

tag a set num

tag is a num is 3000

同步的概念就是共享,如果不是资源共享就没有必要进行同步,同步的目的为了是线程安全,线程安全需要满足两个条件:1原子性2.可见性

当两个线程调用一个对象的不同方法,同步的方法是需要等待获取锁的,不同步的方法可以直接调用

示例如下:

package com.jc.thread;

public class Thread03 {

public synchronized void method1(String threadName) {

System.out.println(threadName);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void method2(String threadName) {

System.out.println(threadName);
}

public static void main(String[] args) {

final Thread03 t = new Thread03();

Thread thread1 = new Thread(new Runnable() {

@Override
public void run() {
t.method1(Thread.currentThread().getName());
}
}, "t1");
Thread thread2 = new Thread(new Runnable() {

@Override
public void run() {
t.method2(Thread.currentThread().getName());
}
}, "t2");

thread1.start();
thread2.start();
}

}
打印结果:
t1

t2

打印间隔,不需要等待两秒,如果需要等待两秒之后打印结果,则是需要两个方法(method1,method2)都需要加上syncronized关键字,衍生出一致性的概念。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: