多个线程分别创建了锁实例后对同一对象加锁的问题

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();
    }
}

}
//求没能实现同步的原因及关于多个线程分别创建了锁实例后对同一对象加锁的问题。

其实不能实现同步的原因先前我有提到:

锁是共享资源才会有效
所以lock不能声明在局部方法内部
至少应当是类成员
tickets 对每个售票点来说应当是单独的
--------------------
我觉得楼主朋友应当专门研究研究进程和线程的执行机制。

锁是共享资源才会有效
所以lock不能声明在局部方法内部
至少应当是类成员
tickets 对每个售票点来说应当是单独的

[code="java"]
package com.maxm.thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TicketsTest {
public static void main(String[] args) {
Thread station1 = new Thread(new TicketsThread(), "售票点1");
Thread station2 = new Thread(new TicketsThread(), "售票点2");
Thread station3 = new Thread(new TicketsThread(), "售票点3");
station1.start();
station2.start();
station3.start();
}

}

class TicketsThread implements Runnable {
int tickets = 0;
Lock lock = new ReentrantLock();

@Override
public void run() {
    while (true) {
        try {
            lock.lock();
            Thread.sleep(50);
            if (tickets < 100) {
                tickets++;
                String tname = Thread.currentThread().getName();
                System.out.println(tname + " 售出第" + tickets + " 张门票");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

}
[/code]

贴一以前写过的代码:

[code="java"]

package com.maxm.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**

  • 测试线程相关东东
  • @author neal
  • */
    public class TestThread {
    public static void main(String[] args) {
    // doSth();
    // doSth2();
    // testDaemon();
    new TestThread().mutex();
    }

    /**

    • 测试锁机制
      */
      Object signal = new Object();
      public void mutex(){
      for(int i = 0; i<5;i++){
      new Thread(new Runnable(){

          public void run(){
      
              synchronized(signal){
                  try{
                      System.out.println("当前线程释放signal的锁,等待1000ms");
                      signal.wait(1000);
                      System.out.println("虚拟机随机唤醒一个等待队列中的线程");
                      signal.notify();
                  } catch(Exception e){
                      e.printStackTrace();
                  }
              }
      
          }
      }).start();
      

      }
      }

    /**

    • 该法有问题 */ private static void testDaemon(){ for(int i=0; i<5; i++){ Thread parent = new Thread(){ public void run(){ int j=0; System.out.println(Thread.currentThread().getName() + " start"); Thread child = new Thread(){ public void run(){ System.out.println(Thread.currentThread().getName() + " start"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } while(true){ System.out.println("child runs"); } } }; child.setDaemon(true); child.setName("child" + j); child.start(); System.out.println(Thread.currentThread().getName() + " ends"); } }; parent.setName("parent-" + i); parent.start(); }

    }

    /**

    • 执行器方式 */ private static void doSth2() { ATask task; ExecutorService service = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { task = new ATask("thread-" + i); service.execute(task); } shutdownAndAwaitTermination(service); }

    /**

    • 查看线程执行任务的顺序
      */
      private static void doSth() {
      ATask task;
      Thread thread;
      // for (int i = 0; i < 1000; i++) {
      int i = 0;
      while(true){
      task = new ATask("thread-" + i);
      i++;
      thread = new Thread(task);
      thread.start();

      /* 
       * 若没这句,则执行线程无任何挂起会一直执行
       * 导致cpu没机会去调度执行其他的线程,造成线程饿死,
       * 切cpu占用率特别高。Thread.sleep可以暂时放弃cpu的执行权,
       * 降低cpu的消耗
       */
      try {
          Thread.sleep(1);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println(task.getName() + " start");
      

      }

// }
}

/**
 * 关闭执行器并等侯其终止
 * 
 * @param pool
 */
private static void shutdownAndAwaitTermination(ExecutorService pool) {
    // 阻止新任务提交
    pool.shutdown();
    try {
        // 取消所有遗留任务
        if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { // 等候超时
            pool.shutdownNow();
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)){
                System.err.println("pool terminate fail");
            }
        }
    } catch (InterruptedException ie) {
        pool.shutdownNow();
        Thread.currentThread().interrupt();
    }
}

/**
 * 某种任务
 * 
 * @author neal
 * 
 */
static class ATask implements Runnable {
    /** task name **/
    private String name;

    ATask(String str) {
        this.name = str;
    }

    public String getName() {
        return name;
    }

    // doSth
    public void run() {
        System.out.println(this.name + " run");
    }
}

}

[/code]

修改第一段代码中while循环无法退出的bug:

[code="java"]
package com.maxm.thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TicketsTest {
public static void main(String[] args) {
Thread station1 = new Thread(new TicketsThread(), "售票点1");
Thread station2 = new Thread(new TicketsThread(), "售票点2");
Thread station3 = new Thread(new TicketsThread(), "售票点3");
station1.start();
station2.start();
station3.start();
}

}

class TicketsThread implements Runnable {
int tickets = 0;
Lock lock = new ReentrantLock();
boolean over = false;

@Override
public void run() {
    while (true) {
        if (over) {
            break;
        }
        try {
            lock.lock();
            Thread.sleep(50);
            if (tickets < 100) {
                tickets++;
                String tname = Thread.currentThread().getName();
                System.out.println(tname + " 售出第" + tickets + " 张门票");
            } else {
                over = true;
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

}
[/code]

改进代码:
[code="java"]
// Thread station1 = new Thread(new TicketsThread(), "售票点1");
// Thread station2 = new Thread(new TicketsThread(), "售票点2");
// Thread station3 = new Thread(new TicketsThread(), "售票点3");
// station1.start();
// station2.start();
// station3.start();

    for (int i = 1; i <= 3; i++) {
        new Thread(new TicketsThread(), "售票点" + i).start();;
    }

[/code]

多个线程分别创建了锁实例后对同一对象加锁,不能实现同步的原因。具体解释一下。谢了

之所以不能实现同步因为你原先每个线程都new了一把锁,
所以各个线程代码段加的不是同一把锁,这当然不会有用了,
因为不会有共享资源的竞争。

现在我有个疑问是:“多个线程分别创建了锁实例后对同一对象加锁”,与“jvm为每个对象都关联了唯一的一把锁”。二者好像矛盾?

‘多个线程分别创建了锁实例后对同一对象加锁‘,这个概念是怎么来的?
首先加锁是针对代码段的,
其次jvm为每个对i象都关联了唯一的一把锁, 所以这每个对象都可以作为锁加在代码段上,

参考 : http://www.iteye.com/topic/164905   ;