Chr*_*haw 0 java multithreading
我正在尝试使用映射实现线程块,以便一次只能在一个客户上处理一个操作.这是与Web服务的对话,需要多个步骤才能完成整个工作流程.我需要能够一次锁定一个客户,但允许其他线程执行而不会阻止流程.
这是我的测试用例,看看如何让它工作.我所看到的是第二个线程doSynchronizedSomething在第一个线程清除之前无法进入同步块.我认为这应该有效,但它没有按预期工作.
结果如下,您会发现毫秒相距三秒钟.我还检查过以确保CustomerLocks在我的测试用例中它们不是同一个对象.这可能吗?
Starting operation 123456 at time 1381173121688
Done with operation for 123456 at time 1381173124689
Starting operation 234567 at time 1381173124689
Done with operation for 234567 at time 1381173127690
Run Code Online (Sandbox Code Playgroud)
码
package simplethreadlock;
public class CustomerLock {
private String customerId;
public CustomerLock(String customerId) {
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
}
package simplethreadlock;
import java.util.concurrent.ConcurrentHashMap;
public class CustomerLockingMap {
private static ConcurrentHashMap<String, CustomerLock> locks = new ConcurrentHashMap<String, CustomerLock>();
public static CustomerLock aquireLock(String customerId) {
CustomerLock lock = locks.get(customerId);
if (lock == null) {
lock = new CustomerLock(customerId);
locks.put(customerId, lock);
}
return lock;
}
}
package simplethreadlock;
import org.junit.Assert;
import org.junit.Test;
public class CutomerLockingTest {
@Test
public void testLock() throws InterruptedException {
final String customerId1 = "123456";
final String customerId2 = "234567";
final CustomerLock customer1Lock1 = CustomerLockingMap
.aquireLock(customerId1);
final CustomerLock customer1Lock2 = CustomerLockingMap
.aquireLock(customerId1);
final CustomerLock customer2Lock1 = CustomerLockingMap
.aquireLock(customerId2);
final CustomerLock customer2Lock2 = CustomerLockingMap
.aquireLock(customerId2);
CountDownLatch latch = new CountDownLatch(1);
Assert.assertNotEquals(customer1Lock1, customer2Lock1);
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer1Lock1, customerId1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer2Lock1, customerId2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer1Lock2, customerId1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
doSynchronziedSomething(customer2Lock2, customerId2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
latch.await(8, TimeUnit.SECONDS);
}
private void doSynchronziedSomething(final CustomerLock lock, final String customerId) throws InterruptedException {
synchronized (lock) {
System.out.println("Starting operation " + customerId + " at time "
+ System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("Done with operation for " + customerId
+ " at time " + System.currentTimeMillis());
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
愚蠢的我是Thread.start()但是如果你看这个例子寻求帮助,我确实添加了CountDownLatch,这样单元测试就不会在线程有时间完成之前退出.
someThread.run()
Run Code Online (Sandbox Code Playgroud)
不是一种启动线程的方法.它只在当前线程中运行该线程的内部runnable,然后才能执行任何后续行.使用.start()实际启动线程的线程,并让两个线程(和主线程)同时运行.
| 归档时间: |
|
| 查看次数: |
235 次 |
| 最近记录: |