对于同步除了同步方法外还可以使用同步代码块有时候同步代码块会带来比同步方法更好的效果
追其同步的根本的目的是控制竞争资源的正确的访问因此只要在访问竞争资源的时候保证同一时刻只能一个线程访问即可因此Java引入了同步代码快的策略以提高性能
在上个例子的基础上对oper方法做了改动由同步方法改为同步代码块模式程序的执行逻辑并没有问题
/**
* Java线程线程的同步同步代码块
*
* @author leizhimin ::
*/
public class Test {
public static void main(String[] args) {
User u = new User(张三 );
MyThread t = new MyThread(线程A u );
MyThread t = new MyThread(线程B u );
MyThread t = new MyThread(线程C u );
MyThread t = new MyThread(线程D u );
MyThread t = new MyThread(线程E u );
MyThread t = new MyThread(线程F u );
tstart();
tstart();
tstart();
tstart();
tstart();
tstart();
}
}
class MyThread extends Thread {
private User u;
private int y = ;
MyThread(String name User u int y) {
super(name);
thisu = u;
thisy = y;
}
public void run() {
uoper(y);
}
}
class User {
private String code;
private int cash;
User(String code int cash) {
de = code;
thiscash = cash;
}
public String getCode() {
return code;
}
public void setCode(String code) {
de = code;
}
/**
* 业务方法
*
* @param x 添加x万元
*/
public void oper(int x) {
try {
Threadsleep(L);
synchronized (this) {
thiscash += x;
Systemoutprintln(ThreadcurrentThread()getName() + 运行结束增加 + x + 当前用户账户余额为 + cash);
}
Threadsleep(L);
} catch (InterruptedException e) {
eprintStackTrace();
}
}
@Override
public String toString() {
return User{ +
code= + code + \ +
cash= + cash +
};
}
}
线程E运行结束增加当前用户账户余额为
线程B运行结束增加当前用户账户余额为
线程D运行结束增加当前用户账户余额为
线程F运行结束增加当前用户账户余额为
线程C运行结束增加当前用户账户余额为
线程A运行结束增加当前用户账户余额为
Process finished with exit code
注意
在使用synchronized关键字时候应该尽可能避免在synchronized方法或synchronized块中使用sleep或者yield方法因为synchronized程序块占有着对象锁你休息那么其他的线程只能一边等着你醒来执行完了才能执行不但严重影响效率也不合逻辑
同样在同步程序块内调用yeild方法让出CPU资源也没有意义因为你占用着锁其他互斥线程还是无法访问同步程序块当然与同步程序块无关的线程可以获得更多的执行时间
本文出自 熔 巖 博客请务必保留此出处