黑马程序员技术交流社区

标题: 线程的练习!从1交替打印到100 [打印本页]

作者: 王士铭    时间: 2011-8-3 00:20
标题: 线程的练习!从1交替打印到100
要求是这个样子的 分别给线程取名字,Thread-a,Thread-b,然后就交替打印数字,我同学给我的一道笔试题,我怎么写都写不出这样子的效果
Thread-a....1
Thread-b....2
Thread-a....3
Thread-b....4
    *
    *
    *
Thread-a....99
Thread-b....100
作者: 匿名    时间: 2011-8-3 07:14
常见的线程通信问题…直接用wait,和notify或者用Condition里功能都可以…建议先看视频,基础或者线程并发库里的都可以。直接拿到代码不是好事
作者: 匿名    时间: 2011-8-3 08:26
标题: 你看这个可以波?
[code=java]package Thread;
public class ThreadAB  extends Thread{
   int i=0;
    private static int count=0;
  private static Object o=new Object();

    public ThreadAB(String ID){
        currentThread().setName(ID);
    }
    public void run() {
        synchronized (o) {
            while(true){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(count%2==0&&currentThread().getName().equals("a")){
                    o.notify();
                  
                    count++;
                    System.out.println("Thread--"+currentThread().getName()+"...."+count);
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else if (count%2==1&&currentThread().getName().equals("b")) {
                    o.notify();
                  
                    count++;
                    System.out.println("Thread--"+currentThread().getName()+"...."+count);
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                }
            }
        }

   
        public static void main(String[] args) {
             ThreadAB b=new ThreadAB("b");
             ThreadAB a=new ThreadAB("a");
            a.setName("a");
            b.setName("b");
            a.start();
            b.start();
           
        }
}[/code]设定一个两个线程的公共变量count。线程启动时第一件事情就是去获得该变量的值,线程a只能在变量为双数时执行,线程b只能在变量为单数时执行,执行完毕后将该数字加一并notify。虽然ab线程会去竞争该变量,但是当a执行完以后如果继续获得变量的控制权,因为数字已经变了。所以a线程继续notify,直到b获取该变量,执行后加一才能轮到a继续执行。
作者: 王士铭    时间: 2011-8-3 09:02
标题: 回复 藤椅 的帖子
学习了,继续等,一定还有更简单的!修改了一下循环条件还是可以用的while (count<100)
明白,但是也敲一遍, 有个地方不是很明白synchronized里面的while(true)里面就不是很明白了,因为Synchronized同步了while(true) 进去后是怎么跳出来的呢?线程A进去了他一直在循环 他就没法跳出来其他线程就没法进去了不知道怎么调出来
[ 本帖最后由 王士铭 于 2011-08-05  14:42 编辑 ]
作者: 匿名    时间: 2011-8-3 12:00
我也是对线程同步问题很困惑,看来半天的视频有又看看书,依葫芦画瓢能出了一下代码:
[code=java]package com.threadtest;

public class ThreadTest {

        /**
         * @param args
         */
        public static void main(String[] args) {
               
                Temp temp=new Temp();
                Thread1 th1 = new Thread1(temp);
                Thread2 th2 = new Thread2(temp);
                Thread t = new Thread(th1);
                Thread t2 = new Thread(th2);
                t.start();
                t2.start();
        }

}

class Thread1 implements Runnable {
        int num = 100;
        Temp temp;
        public Thread1(Temp temp) {
                super();
                this.temp = temp;
        }

        @Override
        public void run() {
                // TODO Auto-generated method stub
                while (num > 0) {
                        if(temp.isFlag()==true){
                                try {
                                        Thread.sleep(1);
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                                System.out.println("Thread1 running "
                                                + num--);
                                temp.flagfalse();
                                
                        }

                }
        }
}

class Thread2 implements Runnable {

        int num = 100;
        Temp temp;
        
        public Thread2(Temp temp) {
                super();
                this.temp = temp;
        }
        @Override
        public void run() {
                // TODO Auto-generated method stub
                while (num > 0) {
                        if(temp.isFlag()==false){
                                try {
                                        Thread.sleep(1);
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                                System.out.println("Thread2 running " + num--);
                                temp.flagtrue();
                        }
                }
        }

}

class Temp {
        private   boolean flag = false;

        public boolean isFlag() {
                return flag;
        }

        public synchronized void flagtrue() {
                this.flag = true;
        }

        public synchronized void flagfalse() {
                this.flag = false;
        }
}[/code]
运行结果跟要求的一样 自己拿去测一下。用到的Temp类中的flag相当于一个公共信号灯一样一个负责开一个负责关




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2