Java并发操作
什么是并发问题。
多个进程或线程同时(或着说在同一段时间内)访问同一资源会产生并发问题。
银行两操作员同时操作同一账户就是典型的例子。比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户减去 50元,A先提交,B后提交。最后实际账户余额为1000-50=950元,但本该为 1000+100-50=1050。这就是典型的并发问题。如何解决?可以用锁。
Java中synchronized的用法
用法1
public class Test
{
public synchronized void print()
{
....;
}
}
某线程执行print()方法,则该对象将加锁。其它线程将无法执行该对象的所有synchronized块。
用法2
public class Test
{
public void print()
{
synchronized(this)
{
//锁住本对象
...;
}
}
}
同用法1, 但更能体现synchronized用法的本质。
用法3
public class Test
{
private String a = "test";
public void print()
{
synchronized(a)
{
//锁住a对象
...;
}
}
public synchronized void t()
{
...; //这个同步代码块不会因为print()而锁定.
}
}
执行print(),会给对象a加锁,注意不是给Test的对象加锁,也就是说 Test对象的其它synchronized方法不会因为print()而被锁。同步代码块执行完,则释放对a的锁。
为了锁住一个对象的代码块而不影响该对象其它 synchronized块的高性能写法:
public class Test
{
private byte[] lock = new byte[0];
public void print()
{
synchronized(lock)
{
...;
}
}
public synchronized void t()
{
...;
}
}
静态方法的锁
public class Test
{
public synchronized static void execute()
{
...;
}
}
效果同
public class Test
{
public static void execute()
{
synchronized()
{
...;
}
}
}
Java中的锁与排队上厕所。
锁就是阻止其它进程或线程进行资源访问的一种方式,即锁住的资源不能被其它请求访问。
在JAVA中,sychronized关键字用来对一个对象加锁。比如:
public class MyStack
{
int idx = 0;
char [] data = new char[6];
public synchronized void push(char c)
{
data[idx] = c;
idx++;
}
public synchronized char pop()
{
idx--;
return data[idx];
}
public static void main(String args[])
{
MyStack m = new MyStack();
/**
下面对象m被加锁。严格的说是对象m的所有synchronized块被加锁。
如果存在另一个试图访问m的线程T,那么T无法执行m对象的push和
pop方法。
*/
(); //对象m被加锁。
}
}
Java的加锁解锁跟多个人排队等一个公共厕位完全一样。
第一个人进去后顺手把门从里面锁住,其它人只好排队等。
第一个人结束后出来时,门才会打开(解锁)。
轮到第二个人进去,同样他又会把门从里面锁住,其它人继续排队等待。
用厕所理论可以很容易明白: 一个人进了一个厕位,这个厕位就会锁住,但不会导致另一个厕位也被锁住,因为一个人不能同时蹲在两个厕位里。
对于Java 就是说:Java中的锁是针对同一个对象的,不是针对class的。看下例:
MyStatck m1 = new MyStack();
MyStatck m2 = new Mystatck();
();
();
m1对象的锁是不会影响m2的锁的,因为它
Java并发 来自淘豆网www.taodocs.com转载请标明出处.