@线程同步
同步就是协同步调,按预定的先后次序进行运行,“同”的意思不是一起运动;同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。
@线程同步什么时候用
在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。
例如下面的情况:
常某现有100元,增加了20元,那么账户的余额是120,减少了60元,那么账户的现有余额就是60元。
如果设置了线程的同步,那么结果会是上面我们说预料的结果,但是如果没有设置同步,可能就会出现我们难以预料的事情。

public class Test {
public static void main(String[] args) {
Person p = new Person("常某", 100);
new MyThread( p, 20).start();
new MyThread( p, -60).start();
new MyThread( p, -80).start();
}
}
class MyThread extends Thread {
private Person p;
private int c= 0;
MyThread( Person p, int c) {
this.p = p;
this.c = c;
}
public void run() {
p.oper(c);
}
}
/**
业务人员
*/
class Person {
private String name;
private int cash;
Person(String name, int cash) {
this.name = name;
this.cash = cash;
}
public void setName( String name){
this.name=name;
}
public String getName(){
return name;
}
/**
计算金钱
*/
public void oper(int c) {
try {
Thread.sleep(10L);
this.cash += c;
System.out.println(name+"的账户增加“" + c+ "”,当前用户账户余额为:" + cash);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
***********************************************************************-
解决同步化问题的方法有两种:
1.同步块
同步块:使具有某个对象见识点的线程,获得运行权限的一种方法,每个对象只能在拥有监视点的情况下,才能获得运行权限。
同步块的结构
synchronized(someobject)
{
...................
}
具体的解决方案如下
public class Test {
public static void main(String[] args) {
Person p = new Person("常某", 100);
new MyThread( p, 20).start();
new MyThread( p, -60).start();
new MyThread( p, -80).start();
}
}
class MyThread extends Thread {
private Person p;
private int c= 0;
MyThread( Person p, int c) {
this.p = p;
this.c = c;
}
public void run() {
synchronized(p){
p.oper(c);
}
}
}
/**
业务人员
*/
class Person {
private String name;
private int cash;
Person(String name, int cash) {
this.name = name;
this.cash = cash;
}
public void setName( String name){
this.name=name;
}
public String getName(){
return name;
}
/**
计算金钱
*/
public void oper(int c) {
try {
Thread.sleep(10L);
this.cash += c;
System.out.println(name+"的账户增加“" + c+ "”,当前用户账户余额为:" + cash);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
2.同步化方法
同步化方法就是对整个方法进行同步。
同步化方法的结构
synchronized void f()
{
..........
}
具体的代码如下:
public class Test {
public static void main(String[] args) {
Person p = new Person("常某", 100);
new MyThread( p, 20).start();
new MyThread( p, -60).start();
new MyThread( p, -80).start();
}
}
/**
创建线程
*/
class MyThread extends Thread {
private Person p;
private int c= 0;
MyThread( Person p, int c) {
this.p = p;
this.c = c;
}
public void run() {
p.oper(c);
}
}
/**
业务人员
*/
class Person {
private String name;
private int cash;
Person(String name, int cash) {
this.name = name;
this.cash = cash;
}
public void setName( String name){
this.name=name;
}
public String getName(){
return name;
}
/**
计算现有账户的总额,同步化方法
*/
public synchronized void oper(int c) {
try {
Thread.sleep(10L);
this.cash += c;
System.out.println(name+"的账户增加“" + c+ "”,当前用户账户余额为:" + cash);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
结果一定是如下:
网上还有很多解决同步化的问题,在这里我只是解决为什么要用线程同步,以及常用的两种方法,其他方法大家也可以尝试,推荐一篇博客:实现同步化的五种方法
转自:http://blog.youkuaiyun.com/changyinling520/article/details/53525256