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 } }