有两个问题请教大虾们:
1.synchronize关键字锁定某个对象,假如线程A锁定,那么线程A在解锁后,是不是马上另一个该对象锁池中的线程B马上开始执行,还是继续执行完线程A的其他代码?2.虚拟机对多线程的主动调度(并不是调用sleep,yield,join方法),也就是虚拟机对A线程执行一段时间后,主动让线程B执行一会,这不是存在很大的偶然性吗?在实际的编程肯定有这种影响吧,理解不是很深刻。

解决方案 »

  1.   

    synchronize解锁后马上给队列中的其他请求获得资源
    效率低啊!
      

  2.   

    1 解锁后线程A当然会继续执行,毕竟是两个线程嘛。
    2 可能不同系统会不一样,NT系统上某个线程运行超过一定的时间片段后会强制切换给别的线程
      

  3.   

    1.多线程之间同步以外的代码不会受到影响,所以你的问题不存在
    2.线程调度并不是一个线程做完或者做一定量才切换到另一个线程
    线程是微秒级切换的,是每一个微妙都有不同的进程/线程在获得CPU时间片,区别在于高优先级的线程有机会获得更多次的时间片而已
      

  4.   

    结合使用,不同环境不同应用。对于 synchronize 关键字,关键在于理解每个对象的对象锁的概念。
      

  5.   

    一般来说synchronize关键用于多个线程共用同一个资源的时候,当A线程用该资源,其余线程需要用此资源的话则需要等待,A用完后释放后,其他线程才能用此资源,线程执行要占用CPU资源,但是CPU资源的调度不是由程序决定的,而是由系统来分配,此时A线程是继续执行还是B线程马上执行这要看系统的分配,但是有一点,就是当A在用共有资源时B想用共有资源的话那只能等待
      

  6.   

    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赋的值
    }
    }
      

  7.   

    线程可以执行的两个条件:
    1.该线程获得了它执行所必须的资源
    2,获得了CPU的执行时间
    问题一:线程A解锁释放资源后,在等待队列中的线程B会马上得到该资源,但是得到了该资源后线程B不是马上就可以执行了,线程得到资源与线程执行是两码事,因为它还要有CPU的执行时间。所以线程B虽然得到了线程A释放的资源,但是这个时候还要看系统把CPU的时间篇分配给了哪个线程,如果是给了A,那么A继续执行,B暂停(虽然它有资源),反之
    问题二:系统分配给各个线程的CPU执行时间确实存在很大的偶然性,这其实就是操作系统中的CPU的调度问题,具体要看系统是采用的哪个CPU调度算法(见计算机操作系统),所以在多线程的程序中,由于不能把握好系统分给各个线程的CPU时间,常常会出现一些莫名其妙的输出结果。
      

  8.   

    The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.