当一个线程进入一个对象的一个synchronized方法后 比如说setI方法,其它线程是否可进入此对象的其它方法非synchronized方法比如getI方法? 这里 会 阻塞吗?public  class  TestA
{
    private int i;    public TestA(){}    public  synchronized void setI(int j)
   {
      this.i = j;
   }    public int getI()
   {
      return this.i;
   }}

解决方案 »

  1.   

    不会,SYNCHRONIZED方法需要对象锁,一个线程用了这个方法,就占用了这个锁,其它的线程没锁进不来,普通方法不用锁,随便进
      

  2.   

    不会阻塞,除非 getI 也置成为同步方法。
      

  3.   

    如果多个线程操作的是同一个对象,那么就会发生阻塞,因为SYNCHRONIZED方法是在对象上加锁,所以一旦某个方法进入了该对象的同步方法,那么该对象就被加锁了,其他线程要想访问该对象就必须等到使用该对象的线程结束使用。
      

  4.   

    被SYNCHRONIZED修饰的方法,当其中一个线程占用了,就持有了该方法的对象锁,别的方法只有得到该对象锁才能调用该方法
    针对其他的方法还是可以访问的
      

  5.   

    public  class  TestA
    {
        private int i;    public TestA(){}    public  synchronized void setI(int j)
       {
          this.i = j;
       }    public int getI()
       {
    synchronized (o){
          return this.i;
    }
       }   private Object o = new Object();}
    如果改成这样呢?会阻塞吗????谢谢了
      

  6.   

        
    还是不会,因为是不同对象的锁,每个对象都有自己的一把隐锁。    public int getI()
       {
           synchronized (o){
             return this.i;
           }
       }
    线程A调用getI()使用的是 private Object o = new Object();中对象o的锁。而public  synchronized void setI(int j)使用的TestA对象的锁。两个线程个用个的锁,不存在同步。吧getI()中的synchronized(o)改成synchronized(this)。
      

  7.   

    package Thread;public class TwoThread {
    public static void main(String[] args) {
    Queue q=new Queue ();//new出一个q:后面的两个线程都是用的同一个q,保证一个put一个get
    Producer p=new Producer (q);//让new出的p去往q里面put
    Customer c=new Customer (q);//让new出的c从q中get
    p.start();//p和q开始的顺序并不报错
    c.start();

    }
    }
    class Producer extends Thread
    {
    Queue q;
    public Producer(Queue q) {
    this.q=q;//给成员变量赋值,再一调运q的put方法
    }
    @Override
    public void run() {
    for (int i = 0; i < 10; i++) {
    q.put(i);//此处只是让q去put  10次
    System.out.println("Producer put "+i);//并且输出本次放的是第几杯
    }
    }
    }
    class Customer extends Thread
    {
    Queue q;
    public Customer(Queue q) {
    this.q=q;//给成员变量赋值,再一调运q的get方法
    }
    @Override
    public void run() {
    while (true) {//死循环:只要q里面有,就去get
    //get方法有返回值,返回值就是producer所put的数量
    //此处也不需要去考虑是第几杯
    //在Queue中的value解决可这一问题:
    //put中的I赋给value,get方法有返回值就value的值
    System.out.println("Customer get "+q.get());
    //如果循环完了,就跳出循环,否则线程不会自己结束
    if (q.value==9) {
    break;
    }
    }

    }
    }
    class Queue
    {
    int value;
    boolean bFull=false;
    public synchronized void put (int i)//在producer中的put方法中就是将其I传进来
    {
    if (!bFull) {//条件为真(如果没满,就倒水)
    value=i;//给value赋值,现在有几杯水
    bFull=true;//满了
    notify();//唤醒其他线程(让customer去get)
    }
    try {
    wait();//告诉customer去get后自己等待customer的get结束
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    public synchronized int get()
    {
    if (!bFull) {//如果没满就等待,如果满了就不进    **这就是为什么main里面谁先开始不报错的原因**
    //get和put方法中的if条件判断起到了至关重要的作用
    try {
    wait();
    } catch (InterruptedException e) {

    e.printStackTrace();
    }
    }
    bFull =false;//赋值为没满
    notify();//唤醒producer去put
    return value;//get的返回值就是put的时候给value赋的值
    }
    }