黑马程序员技术交流社区
标题:
对同一对象加锁,如何实现同步?
[打印本页]
作者:
张凯
时间:
2012-7-20 17:39
标题:
对同一对象加锁,如何实现同步?
package ThreadTest;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TicketTest {
public static void main(String[] args) {
TicketsThread tt = new TicketsThread();
Thread station1 = new Thread(tt, "售票点1");
Thread station2 = new Thread(tt, "售票点2");
Thread station3 = new Thread(tt, "售票点3");
station1.start();
station2.start();
station3.start();
}
}
class TicketsThread implements Runnable {
int tickets = 0;
public void run() {
Lock lock = new ReentrantLock();//注意在run方法中
while (true) {
lock.lock();
if (tickets < 100) {
tickets++;
System.out.println(Thread.currentThread().getName() + "售出第"
+ tickets + "张票");
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
}
}
复制代码
多个线程分别创建了锁实例后对同一对象加锁,不能实现同步的原因。具体解释一下。谢了
现在我有个疑问是:“多个线程分别创建了锁实例后对同一对象加锁”,与“jvm为每个对象都关联了唯一的一把锁”。二者好像矛盾?
作者:
王宝康
时间:
2012-7-20 18:02
本帖最后由 王宝康 于 2012-7-20 18:09 编辑
package thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TicketTest {
public static void main(String[] args) {
TicketsThread tt = new TicketsThread();
Thread station1 = new Thread(tt, "售票点1");
Thread station2 = new Thread(tt, "售票点2");
Thread station3 = new Thread(tt, "售票点3");
station1.start();
station2.start();
station3.start();
}
}
class TicketsThread implements Runnable {
int tickets = 0;
Lock lock = new ReentrantLock();//这儿,你把锁定义到了run()方法时,所有的线程都会运行run()方法,然后new了它们自己的lock对象,各自持有自己的锁
//所以没能实现同步
public void run() {
// 注意在run方法中
while (true) {
lock.lock();
if (tickets < 100) {
tickets++;
System.out.println(Thread.currentThread().getName() + "售出第"
+ tickets + "张票");
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
lock.unlock();//这儿,你的代码中,没有把lock.unlock()用finally包起来,这儿是一定要用finally包起来的,
//保证它必须运行来释放锁,以使别的线程有机会获得锁
}
}
}
}
复制代码
作者:
themoon
时间:
2012-7-20 18:43
线程的同步是为了阻止在两个及两个以上的线程同时运行时,在对同一资源的访问时发生的冲突。对于你的这段程序来说,你声明的三个线程都应该遵循待前一个线程完全释放了资源之后,下一个线程才可以访问的。
具体应该这样加锁:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TicketTest {
public static void main(String[] args) {
TicketsThread tt = new TicketsThread();
Thread station1 = new Thread(tt, "售票点1");
Thread station2 = new Thread(tt, "售票点2");
Thread station3 = new Thread(tt, "售票点3");
station1.start();
station2.start();
station3.start();
}
}
class TicketsThread implements Runnable {
int tickets = 0;
public void run() {
Lock lock = new ReentrantLock();// 注意在run方法中
while (true) {
lock.lock();
if (tickets < 100) {
tickets++;
System.out.println(Thread.currentThread().getName() + "售出第" + tickets + "张票");
}
try {
Thread.sleep(50);
lock.unlock();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
而你说的另一个问题:“多个线程分别创建了锁实例后对同一对象加锁”,与“jvm为每个对象都关联了唯一的一把锁”。二者好像矛盾?
以你的代码来看,这句话是矛盾的,因为你每个线程都是共享同一实例。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2