Thread种/java多线程(代码篇)

Thread类/java多线程(代码篇)
//线程同步练习
public class ThreadNoSynchronized {
    public static void main(String argv[ ]){
          ShareData oShare = new ShareData();//创建,初始化 ShareData 对象 oShare
          ThreadDemo th1 = new ThreadDemo("Thread1",oShare);//创建线程 th1
          ThreadDemo th2 = new ThreadDemo("Thread2",oShare);//创建线程 th2
          th1.start();//启动线程 th1
          th2.start();//启动线程 th2
    }
}

class ShareData{
     public static String szData = "";//声明,并初始化字符串数据域,作为共享数据

}
class ThreadDemo extends Thread{
     private ShareData oShare;//声明,并初始化 ShareData 数据域
     ThreadDemo(){}//声明,并实现 ThreadDemo 构造方法
     //声明,并实现 ThreadDemo 带参数的构造方法
     ThreadDemo(String szName,ShareData oShare){
           super(szName);//调用父类的构造方法
           this.oShare = oShare;//初始化 oShare 域
     }
     @SuppressWarnings("static-access")
	public void run(){
    	 //synchronized (oShare) {  //加上本行代码,实现线程同步,线程有序执行
    	   //不加上面代码为线程异步,会出现“线程赛跑”现象
           for (int i = 0; i < 5; i++){
                  if (this.getName().equals("Thread1")){
                         oShare.szData = "这是第 1 个线程";
                         //为了演示产生的问题,这里设置一次睡眠
                         try{
                        	 Thread.sleep((int)Math.random() * 100);//休眠
                         }
                         catch(InterruptedException e){//捕获异常
                        	 e.printStackTrace();
                         }
                         System.out.println(this.getName() + ":" + oShare.szData); //输出字符串信息
                         }else if(this.getName().equals("Thread2")){
                         oShare.szData = "这是第 2 个线程";
                         //为了演示产生的问题,这里设置一次睡眠
                         try{
                               Thread.sleep((int)Math.random() * 100); //线程休眠
                         }catch(InterruptedException e){//捕获异常
                        	 e.printStackTrace();
                         }
                         System.out.println(this.getName() + ":" + oShare.szData); //输出字符串信息
                  }
           }
    	 //}
     }
}

//线程优先级练习
public class ThreadPriority{
    public static void main(String args[ ]){
         //用 Thread 类的子类创建线程
         InheritThread itd=new InheritThread();
         //用 Runnable 接口类的对象创建线程
         Thread rtd=new Thread(new RunnableThread());
         itd.setPriority(5);//设置 myThread1 的优先级 5
         rtd.setPriority(5);//设置 myThread2 的优先级 5
         itd.start();//启动线程 itd
         rtd.start();//启动线程 rtd
  }
}
//设置线程优先级
class InheritThread extends Thread {
            //自定义线程的 run()方法
            public void run(){
                    System.out.println("我是InheritThread");//输出字符串信息
                    for(int i=0;i<10;i++){
                            System.out.println(" InheritThread: i="+i);//输出信息
                            try{
                                 Thread.sleep((int)Math.random()*1000); //线程休眠,休眠时间为1000内的随机数
                          }
                          catch(InterruptedException e)//捕获异常
                          {}
                  }
            }
}
//通过 Runnable 接口创建的另外一个线程
class RunnableThread implements Runnable{
       //自定义线程的 run()方法
       public void run(){
              System.out.println("我是RunnableThread");//输出字符串信息
              for(int i=0;i<10;i++){
                    System.out.println("RunnableThread : i="+i);//输出 i
                    try{
                            Thread.sleep((int)Math.random()*1000);//线程休眠,休眠时间为1000内的随机数
                    }
                    catch(InterruptedException e){//捕获异常
                    }
          }
     }
}

/*
 		多线程之间通信
本例子 模拟了生产者和消费者的关系。开始消费者调用消费方法时处于等待状
态,此时唤起生产者线程。生产者开始生产共享数据之后,消费者进行消费,但是当共享数
据为空,所有消费者必须等待,生产者继续生产,然后消费者再次消费,如此循环直到程序
运行最后,可以看到线程一直等待。注意这个线程进入等待后没有其他线程唤醒,除非强行
退出 JVM 环境,否则它一直等待。
注意:考虑到程序的安全性,多数情况下使用 notifiAll(),除非明确可以知道唤醒哪一个
线程。wait 方法调用的前提条件是当前线程获取了这个对象的锁,也就是说 wait 方法必须放
在同步块或同步方法中。
 */
public class ThreadCommunication{
     public static void main(String[ ] args){
          Queue q = new Queue();		//创建,并初始化一个队列
          Producer p = new Producer(q); //创建,并初始化一个生产者
          Consumer c = new Consumer(q); //创建,并初始化一个消费者
          c.start(); //消费者线程启动
          p.start(); //生产者线程启动
     }
}
//生产者消费者线程
class Producer extends Thread{//实现生产者线程
    Queue q;//声明队列 q
	Producer(Queue q){ //生产者构造方法
	     this.q = q; //队列 q 初始化
	}
	public void run(){
	     for(int i=1;i<5;i++){  //循环添加元素
	           q.put(i);  //给队列中添加新的元素
	     }
	}
}

class Consumer extends Thread{
    Queue q;  //声明队列 q
	Consumer(Queue q){ //消费者构造方法
	     this.q = q;  //队列 q 初始化
	}
	public void run(){
	     while(true){  //循环消费元素
	         q.get();  //获取队列中的元素
	     }
	}
}

class Queue{
    int value = 0;//声明,并初始化整数类型数据域 value
    boolean isEmpty = true;//声明,并初始化布尔类型数据域 isEmpty,用于判断队列的状态
      //生产者生产方法
    public synchronized void put(int v){
        //如果共享数据没有被消费,则生产者等待
        if (!isEmpty){
              try{
                   System.out.println("生产者等待");
                   wait();//进入等待状态
              }
              catch(Exception e){//捕获异常
                   e.printStackTrace();//异常信息输出
              }
	     }
	     value += v;//value 值加 v
         isEmpty = false;//isEmpty 赋值为 false
         System.out.println("生产者共生产数量:"+v);//输出字符串信息
         notify();//生产之后通知消费者消费
    }
    //消费者消费的方法
    public synchronized int get(){
         //消费者消费前,如果共享数据已经被消费完,则消费者等待
         if (isEmpty){
            try{
               System.out.println("消费者等待");//输出字符串信息
                 wait();//进入等待状态
            }
            catch(Exception e){//捕获异常
                 e.printStackTrace();//异常信息输出
            }
         }
         value--;//value 值-1
         if (value < 1){
               isEmpty = true;//isEmpty 赋值 true
         }
         System.out.println("消费者消费一个,剩余:"+value);//输出信息
         notify();//消费者消费后,通知生产者生产
         return value;//返回 value
     }
}