本帖最后由 water0_ 于 2014-04-24 21:32:33 编辑

解决方案 »

  1.   

    你这里有两个类T1和T2,你创建了两个不同类的对象,而synchronized只能锁住同一个类的同一个实例对象,因为每个对象都有一个内置锁,该锁只能同时被一个线程拥有,且运行完该方法时才会释放锁。而你这里是不同类的不同对象,这两个对象的分别拥有两个内置锁,所以可以分别被两个线程持有。线程1并不会等待线程2运行完该方法后才运行。很有可能两个线程在都执行完notify后,先后进入阻塞状态。假设先前最最近显示的是奇数,很有可能在两个线程都唤醒后,还是显示奇数的那个线程抢到CPU而继续打印奇数。总之这里有两个内置锁,相互之间不影响锁的占有。
      

  2.   

    package com.thread;public class OddThread extends Thread {
    private Object prev;
    private Object self;
    private int count = 1;
    public OddThread(Object prev, Object self) {
    this.prev = prev;
    this.self = self;
    } @Override
    public void run() {
    int result = count * 2 - 1;
    while (result < 50) {
    synchronized (prev) {
    synchronized (self) {
    System.out.println(result);
    count++;
    self.notify();
    result = count * 2 - 1;
    }
    if (result >= 50) {
    break;
    }
    try {
    prev.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } }}package com.thread;public class EvenThread extends Thread {
    private Object prev;
    private Object self;
    private int count = 1;
    public EvenThread(Object prev, Object self) {
    this.prev = prev;
    this.self = self;
    } @Override
    public void run() {
    int result = count * 2;
    while (result <= 50) {
    synchronized (prev) {
    synchronized (self) {
    System.out.println(result);
    count++;
    self.notify();
    result = count * 2;
    }
    if (result > 50) {
    break;
    }
    try {
    prev.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } }}package com.thread;public class NumberTest {
    public static void main(String[] args) {
    Object a = new Object();
    Object b = new Object();
    OddThread pa = new OddThread(b, a);
    EvenThread pb = new EvenThread(a, b);
    new Thread(pa).start();
    new Thread(pb).start();
    }
    }这是我借鉴以前网上看到的类似问题修改后的代码,应该可以解决你的问题
      

  3.   


    你只需用个同步块就可以了:示例:public class NumberTest{
    public static void main(String[] args) {
    T1 t1 = new T1();
    T2 t2 = new T2();
    t2.start();
    t1.start();
    }
    }
    class T1 extends Thread { @Override
    public void run() {
    synchronized (NumberTest.class) {
    for (int i = 1; i <= 50; i++) {
    System.out.println(i * 2);
    NumberTest.class.notify();
    try {
    NumberTest.class.wait(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }}class T2 extends Thread { @Override
    public void run() {
    synchronized (NumberTest.class) {
    for (int i = 1; i <= 50; i++) {
    System.out.println(i * 2 - 1);
    NumberTest.class.notify();
    try {
    NumberTest.class.wait(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
      

  4.   

    public class ThreadTest
    {
        static boolean isT1 = false; 
        public static void main(String[] args)
        {
            final T1 t1 = new T1();
            final T2 t2 = new T2();
            new Thread()
            {
                @Override
                public void run() 
                {
                    for(int i = 1; i <= 50; i++)
                    {
                        t1.printf(i);
                    }
                };
                
            }.start();
            
            
            new Thread()
            {
                @Override
                public void run() 
                {
                    for(int i = 1; i <= 50; i++)
                    {
                        t2.printf(i);
                    }
                };
            }.start();
        }
    }
    class T1
    {
        public void printf(int i)
        {
            synchronized (ThreadTest.class)
            {
                while(!ThreadTest.isT1)
                {
                    try
                    {
                        ThreadTest.class.wait();
                    }
                    catch (InterruptedException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
                System.out.println(i * 2);
                ThreadTest.isT1 = false;
                ThreadTest.class.notify();
            }
        }
    }class T2
    {
        public void printf(int i)
        {
            synchronized (ThreadTest.class)
            {
                while(ThreadTest.isT1)
                {
                    try
                    {
                        ThreadTest.class.wait();
                    }
                    catch (InterruptedException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
                System.out.println(i * 2 - 1);
                ThreadTest.isT1 = true;
                ThreadTest.class.notify();
            }
        }
    }
      

  5.   


    你只需用个同步块就可以了:示例:public class NumberTest{
    public static void main(String[] args) {
    T1 t1 = new T1();
    T2 t2 = new T2();
    t2.start();
    t1.start();
    }
    }
    class T1 extends Thread { @Override
    public void run() {
    synchronized (NumberTest.class) {
    for (int i = 1; i <= 50; i++) {
    System.out.println(i * 2);
    NumberTest.class.notify();
    try {
    NumberTest.class.wait(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }}class T2 extends Thread { @Override
    public void run() {
    synchronized (NumberTest.class) {
    for (int i = 1; i <= 50; i++) {
    System.out.println(i * 2 - 1);
    NumberTest.class.notify();
    try {
    NumberTest.class.wait(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    不好意思,你这段代码是有问题的,无法保证T1和T2的初始的先后执行顺序
      

  6.   


    你只需用个同步块就可以了:[/code]
    由于wait方法会释放锁,无法保证数字打印的顺序
    改正一下示例:public class NumberTest{
    public static void main(String[] args) {
    Number num = new Number();
    T1 t1 = new T1(num);
    T2 t2 = new T2(num);
    t2.start();
    t1.start();
    }
    }
    class T1 extends Thread {
    Number num;

    T1 (Number num){
    this.num = num;
    }
    @Override
    public void run() {
    while(num.getNum() < 100){
    num.printEven();
    }
    }}class T2 extends Thread {
    Number num;
    T2 (Number num){
    this.num = num;
    }
    @Override
    public void run() {
    while(num.getNum() < 100){
    num.printOdd();
    }
    }
    }class Number{
    int i = 1;

    public synchronized void printOdd(){
    while(i % 2 != 1){
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    if(i<=100)
    System.out.println(i);
    i++;
    notifyAll();
    }

    public synchronized void printEven(){
    while(i % 2 != 0){
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    if(i<=100)
    System.out.println(i);
    i++;
    notifyAll();
    }

    public synchronized int getNum(){
    return i;
    }
    }