Java 程序中的多线程(二)

2014-11-24 09:19:37 · 作者: · 浏览: 1
but don‘t use shared resources
}
}
4.synchronized后面括号里是类。例如:
class ArrayWithLockOrder{
private static long num_locks = 0;
private long lock_order;
private int[] arr;
public ArrayWithLockOrder(int[] a)
{
arr = a;
synchronized(ArrayWithLockOrder.class) {//-----------------------------------------这里
num_locks++; // 锁数加 1。
lock_order = num_locks; // 为此对象实例设置唯一的 lock_order。
}
}
public long lockOrder()
{
return lock_order;
}
public int[] array()
{
return arr;
}
}
class SomeClass implements Runnable
{
public int sumArrays(ArrayWithLockOrder a1,
ArrayWithLockOrder a2)
{
int value = 0;
ArrayWithLockOrder first = a1; // 保留数组引用的一个
ArrayWithLockOrder last = a2; // 本地副本。
int size = a1.array().length;
if (size == a2.array().length)
{
if (a1.lockOrder() > a2.lockOrder()) // 确定并设置对象的锁定
{ // 顺序。
first = a2;
last = a1;
}
synchronized(first) { // 按正确的顺序锁定对象。
synchronized(last) {
int[] arr1 = a1.array();
int[] arr2 = a2.array();
for (int i=0; i value += arr1[i] + arr2[i];
}
}
}
return value;
}
public void run() {
//...
}
}
对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁。
以上4种之间的关系:
锁是和对象相关联的,每个对象有一把锁,为了执行synchronized语句,线程必须能够获得synchronized语句中表达式指定的对象的锁,一个对象只有一把锁,被一个线程获得之后它就不再拥有这把锁,线程在执行完synchronized语句后,将获得锁交还给对象。
在方法前面加上synchronized修饰符即可以将一个方法声明为同步化方法。同步化方法在执行之前获得一个锁。如果这是一个类方法,那么获得的锁是和声明方法的类相关的Class类对象的锁。如果这是一个实例方法,那么此锁是this对象的锁。synchronzied块后面跟类的具体详细例子:
public class DB2_JDBCFactory {
private static DB2_JDBCFactory instance = null;
public static final ThreadLocal threadLocal = new ThreadLocal();
private DB2_JDBCFactory() {
}
public static DB2_JDBCFactory getInstance() {
if(instance == null) {
synchronized(DB2_JDBCFactory.class) { //synchronized后面跟一个类
instance = new DB2_JDBCFactory();
}
}
return instance;
}
public Connection getConnection_JNDI_localhost(){
Connection c = (Connection) threadLocal.get();
try {
if (c == null || c.isClosed()) {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/localhost");
c = ds.getConnection();
threadLocal.set(c);
}
} catch (Exception ex) {
System.err.println("getConnection_JNDI Initial failed. " + ex);
return null;
}
return c;
}
} 外面的对象访问这个类的 需要通过调用它的getInstance()