A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 陈振兴 于 2012-7-13 17:51 编辑

package com.blackhorse.xinglefly;

import java.util.ArrayList;

/**
* 写两个线程,一个线程打印1-52,另一个线程答应字母A-Z。打印顺序为12A34B56C……5152Z。通过使用线程之间的通信协调关系
* 注:分别给两个对象构造一个对象o,数字每打印两个或字母每打印一个就执行o.wait()。在o.wait()之前不要忘了写o.notify()。
* @author xinglefly
* @version 1
*/
public class Thread4 {
        public static void main(String[] args)throws Exception{
                //随机产生26个字母的表示方法
                String chars = "abcdefghijklmnopqrstuvwxyz";
//                System.out.println(chars.charAt((int)(Math.random()*26)));
                ArrayList list = new ArrayList();
                for(char c='a';c<='z';c++){
                        list.add(c);
                }
                String str = "";
                for(int i=0;i<26;i++){
                        int num = (int)(Math.random()*26);
                        str = str+list.get(num);
                }       
                System.out.println(str);
               
                //------------------------------------
                Object obj = new Object();
                ThreadTest1 t1 = new ThreadTest1(obj);
                ThreadTest1 t2 = new ThreadTest1(obj);
                t1.start();
                t2.start();
        }
}
//线程打印1-52
class ThreadTest1 extends Thread{
        private Object obj;
        public ThreadTest1(Object obj){
                this.obj=obj;
        }
        public void run(){
                synchronized(obj){
                        for(int i=1;i<53;i++){
                                System.out.print(i+" ");
                                if(i%2==0){
                                        //唤醒其他线程
                                        this.notifyAll();
                                        try{
                                                obj.wait();
                                        }catch(InterruptedException e){
                                                e.printStackTrace();
                                        }
                                }
                        }
                }
        }
}
//线程打印字母
class ThreadTest2 extends Thread{
        private Object obj;
        public ThreadTest2(Object obj){
                this.obj=obj;
        }
        public void run(){
                synchronized(obj){
                        for(int i=0;i<26;i++){
                                System.out.print((char)('A'+i)+"");
                                //唤醒其它线程
                                obj.notifyAll();
                                try{
                                        if(i!=25){
                                                obj.wait();
                                        }
                                }catch(InterruptedException e){
                                        e.printStackTrace();
                                }
                        }
                }
        }
}
希望指点!我也在查!

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

10 个回复

倒序浏览
1.main函数中t1和t2都是ThreadTest1,把一个改成ThreadTest2
2.ThreadTest1的run方法中,obj.notifyAll你写成了this.notifyAll
回复 使用道具 举报
1.main函数中t1和t2都是ThreadTest1,把一个改成ThreadTest2
2.ThreadTest1的run方法中,obj.notifyAll你写成了this.notifyAll
3.int num = (int)(Math.random()*26+1);
public class Thread4 {
        public static void main(String[] args)throws Exception{
                //随机产生26个字母的表示方法
                //String chars = "abcdefghijklmnopqrstuvwxyz";
//                System.out.println(chars.charAt((int)(Math.random()*26)));
                ArrayList list = new ArrayList();
                for(char c='a';c<='z';c++){
                        list.add(c);
                }
                String str = "";
                for(int i=0;i<26;i++){
                        int num = (int)(Math.random()*26+1);
                        str = str+list.get(num);
                }        
                System.out.println(str);
               
                //------------------------------------
                Object obj = new Object();
                ThreadTest1 t1 = new ThreadTest1(obj);
                ThreadTest2 t2 = new ThreadTest2(obj);
                t1.start();
                t2.start();
        }
}
//线程打印1-52
class ThreadTest1 extends Thread{
        private Object obj;
        public ThreadTest1(Object obj){
                this.obj=obj;
        }
        public void run(){
                synchronized(obj){
                        for(int i=1;i<53;i++){
                                System.out.print(i+" ");
                                if(i%2==0){
                                        //唤醒其他线程
                                        obj.notifyAll();
                                        try{
                                                obj.wait();
                                        }
                                        catch(InterruptedException e){
                                                e.printStackTrace();
                                        }
                                }
                        }
                }
        }
}
//线程打印字母
class ThreadTest2 extends Thread{
        private Object obj;
        public ThreadTest2(Object obj){
                this.obj=obj;
        }
        public void run(){
                synchronized(obj){
                        for(int i=0;i<26;i++){
                                System.out.print((char)('A'+i)+"");
                                //唤醒其它线程
                                obj.notifyAll();
                                try{
                                        if(i!=25){
                                                obj.wait();
                                        }
                                }catch(InterruptedException e){
                                        e.printStackTrace();
                                }
                        }
                }
        }
}

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 赞一个!

查看全部评分

回复 使用道具 举报
温少邦 发表于 2012-7-11 17:34
1.main函数中t1和t2都是ThreadTest1,把一个改成ThreadTest2
2.ThreadTest1的run方法中,obj.notifyAll你写成 ...

ok!较大意将Thread2未改,但是obj.notifyAll()是对象锁的线程释放锁,需要把它放到一个同步段里。
我查了一个public AtomicInteger currentThreadCount = new AtomicInteger();意味着需要访问临界资源,我最终想问一下这临界资源指的是什么,能给我简单说一下吗?给个简单列子
回复 使用道具 举报
问题已解决!我先撤了,明天再深入,以后我会注意自己的代码书写!
谁能给大家讲解一下什么是临界资源!举个简单明了的列子,
回复 使用道具 举报
陈振兴 发表于 2012-7-11 18:01
问题已解决!我先撤了,明天再深入,以后我会注意自己的代码书写!
谁能给大家讲解一下什么是临界资源!举 ...

临界资源就是在同一时间内只能有一个线程访问的资源。。例如打印机,一次只能有一个程序去访问,如果多个程序都可以同时访问,那打印出来的东西就乱了。所以打印机同一时间只能有不大于一个的程序去访问,打印机就属于临界资源。
回复 使用道具 举报
有个关于wait和notify的问题,想让大家帮帮忙
线程在等待和被告知运行时,是先wait然后notify,还是先notify再wait呢?
两者有什么区别么?

在这个程序中调换位置后程序就不能执行了,但是像这个,如下
  1. public class Sample {
  2.         private int number;
  3.        
  4.         public synchronized void increase() {
  5.                
  6.                 while(number != 0) {
  7.                         try {
  8.                                 wait();
  9.                         } catch (InterruptedException e) {
  10.                                 e.printStackTrace();
  11.                         }
  12.                 }
  13.                 number++;
  14.                 System.out.println(number);
  15.                
  16.                 notify();
  17.         }
  18.        
  19.         public synchronized void decrease() {
  20.                
  21.                 while(number == 0) {
  22.                         try {
  23.                                 wait();
  24.                         } catch (InterruptedException e) {
  25.                                 e.printStackTrace();
  26.                         }
  27.                 }
  28.                 number--;
  29.                 System.out.println(number);
  30.                
  31.                 notify();
  32.         }
  33. }
复制代码
就是正确的,为什么?
回复 使用道具 举报
haiyualong 发表于 2012-7-12 10:32
临界资源就是在同一时间内只能有一个线程访问的资源。。例如打印机,一次只能有一个程序去访问,如果多个 ...

ok,谢谢!刚才查了一下这知识点,算是理解了吧!
回复 使用道具 举报
张天天 发表于 2012-7-12 11:14
有个关于wait和notify的问题,想让大家帮帮忙
线程在等待和被告知运行时,是先wait然后notify,还是先notif ...

按原理来说首先是wait,然后是notify(基于对加锁的资源才应用),在运行状态中,线程调用wait(),此时表示线程将释放自己的所标记,同时进入这个对象的等待队列(阻塞状态),需要notify来唤醒线程。
你对比两个程序问的此问题,简单说吧,run方法中需要while判断语句,while放置程序饶过判断条件而造成越界。我把之前的程序那个notify放在后面他就是不执行的。对于深入的解说我还不能说,因为Thread是一个特别深奥的东西,以之前的基础来做后盾的。
回复 使用道具 举报
package com.blackhorse.xinglefly;


import com.blackhorse.xinglefly.Thread5Test.Person3;

/**
* 临界资源访问
* @author xinglefly
* @version 1
*/
class Thread5 {
        public static void main(String[] args){
                Thread5Test t = new Thread5Test();
                Person3 p1 = t.new Person3();
                Person3 p2 = t.new Person3();
       
        p1.start();
        p2.start();
        }       
}

class Thread5Test{
        int beans =20;
        public synchronized int getBeans(){
                if(beans==0)
                        throw new RuntimeException("没了");
                Thread.yield();
                return beans--;
        }
       
        class Person3 extends Thread{
                public void run(){
                        while(true){
                                int bean = getBeans();
                                System.out.println(Thread.currentThread().getName()+"拿到"+bean);
                                Thread.yield();//交出执行权
                        }
                }
        }       
}
以上是简单的程序!
我晕,刚才我老大看见我写线程,说教了半个小时,下次我得悠着点,贴未结,明天中午接着查次类知识!刨根问底来个究竟,带着昨天的问题,今天下午看了一会感觉又有些领悟了。
回复 使用道具 举报
临界资源正如视频上所述就是临时资源。须深入了解及掌握!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马