zoukankan      html  css  js  c++  java
  • Java的多线程机制

    1.利用Thread的子类创建线程

    例1.用Thread子类创建多线程程序。

    先定义一个Thread的子类,该类的run方法只用来输出一些信息。

    package thread;
    
    public class myThread extends Thread{
        private static int count=0;
        
        public void run() {
            int i;
            for(i=0;i<100;i++){
                count=count+1;
                System.out.println("My name is "+getName()+" count="+count);
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        public myThread(String name){
            super(name);
        }
        
    }

    下面用程序来创建线程对象并运行该线程对象。

    package thread;
    
    public class mulThread {
    
        public static void main(String[] args) {
            myThread trFirst,trSecond;
            trFirst = new myThread("First Thread");
            trSecond = new myThread("Second Thread");
            trFirst.start();
            trSecond.start();
            System.out.println("主线程结束!");
        }
    
    }

    2.实现Runnable接口创建线程

    例2. 继承Runnable接口实现多线程。

    package thread;
    
    public class ThreadImRunable implements Runnable{
        private static int count=0;
        private Thread t;
        public void run() {
            int i;
            for(i=0;i<100;i++){
                count++;
                System.out.println("My name is "+t.getName()+" count="+count);
                try {
                    t.sleep(10);
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }    
        }
        
        public ThreadImRunable(String name){
            t = new Thread(this,name);
        }
        
        public void start(){
            t.start();
        }
    }

    主程序跟前面相同。

    package thread;
    
    public class mulThread {
    
        public static void main(String[] args) {
            myThread trFirst,trSecond;
            trFirst = new myThread("First Thread");
            trSecond = new myThread("Second Thread");
            trFirst.start();
            trSecond.start();
            System.out.println("主线程结束!");
        }
    
    }

    3.使用isAlive()和join()等待子线程结束

    例3. join()方法使用示例。

    package thread;
    
    public class demoJoin {
        public static void main(String[] args){
            myThread trFirst,trSecond;
            trFirst = new myThread("First Thread");
            trSecond = new myThread("Second Thread");
            try {
                trFirst.start();
                trSecond.start();
                trFirst.join();
                trSecond.join();
            } catch (InterruptedException e) {
                System.out.println("主线程被中断!");
            }
            System.out.println("主线程结束!");
        }
    }

    4.设置线程优先级

    例4. 设置线程优先级示例。

    package thread;
    
    public class clicker extends Thread{
        private int click=0;
        private volatile boolean running=true;//volatile告诉编译器,不要自作主张为它编译优化
        public int getClick(){
            return click;
        }
        
        public void run() {
            while(running){
                click = click + 1;
            }
        }
        
        public void normalStop(){
            running = false;
        }
        
    }

    程序中的循环变量running被声明成volatile,这个关键字告诉编译器,不要自作主张为它进行编译优化。

    注意:不要将循环体中“click=click+1”改成“++click”的形式。对于前者,编译器会生成多条命令,执行过程中系统有机会将它中断。而后者只有一条指令,系统不能将其中断,这样其他进程就难以有机会使用CPU。

    package thread;
    
    public class demoPri {
    
        public static void main(String[] args) {
            clicker c1High,c2Low;
            c1High=new clicker();
            c2Low=new clicker();
            c1High.setPriority(Thread.NORM_PRIORITY+2);
            c2Low.setPriority(Thread.NORM_PRIORITY-2);
            c2Low.start();
            c1High.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            c1High.normalStop();
            c2Low.normalStop();
            
            try {
                c1High.join();
                c2Low.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("c1High执行循环的次数为:"+c1High.getClick());
            System.out.println("c2Low 执行循环的次数为:"+c2Low.getClick());
        }
    
    }

    程序的输出结果为:

    c1High执行循环的次数为:427835536
    c2Low 执行循环的次数为:396647205

    结果表明,优先级高的线程获得了更多的CPU运行时间。

    5.线程的互斥

    例5. 线程互斥示例。

    package thread;
    
    public class mutixThread extends Thread{
        private static int count = 0;
        private synchronized static void change(Thread t){
            count = count + 1;
            System.out.println("My name is "+t.getName()+" count="+count);
        }
        
        public void run() {
            int i;
            for(i=0;i<100;i++){
                change(this);
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
        public mutixThread(String name){
            super(name);
        }
    }

    下面写一个程序测试它的运行情况。

    package thread;
    
    public class demoMutix {
        public static void main(String[] args){
            mutixThread t1,t2,t3;
            t1 = new mutixThread("First Thread");
            t2 = new mutixThread("Second Thread");
            t3 = new mutixThread("Third Thread");
            t1.start();
            t2.start();
            t3.start();
            try {
                t1.join();
                t2.join();
                t3.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            System.out.println("主线程结束");
        }
    }

    程序运行结果如下:

    .....
    My name is Third Thread count=297
    My name is First Thread count=298
    My name is Third Thread count=299
    My name is Second Thread count=300
    主线程结束

    6.线程的同步

    例6. 线程同步示例。

    package thread;
    
    public class commSource {
        static boolean flag = true;
        static int data;
        static int count;
    }
    package thread;
    
    public class setDataThread extends Thread {
        private readDataThread otherThread=null; //存储另外一个线程对象
        public void run(){
            for(int i=0;i<100;i++){
                if(!commSource.flag)
                    try {
                        synchronized(this){ //锁定当前对象
                        wait(); //阻塞自己
                        }
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                commSource.flag = false;
                commSource.data = (int)(Math.random()*1000);
                commSource.count++;
                System.out.println("设置数据:"+commSource.data+" count="+commSource.count);
                synchronized(otherThread){ //锁定另外一个线程对象
                    otherThread.notify();  //唤醒另外一个线程对象
                }
            }
        }
        public void setOtherThread(readDataThread rt){
            otherThread=rt;
        }
    }
    package thread;
    
    public class readDataThread extends Thread{
        private setDataThread otherThread = null;
        public void run(){
            for(int i=0;i<100;i++){
                if(commSource.flag)
                    try {
                        synchronized(this){
                            wait();
                        }
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                commSource.flag = true;
                System.out.println("获得数据:"+commSource.data);
                synchronized(otherThread){
                    otherThread.notify();
                }
            }
        }
        public void setOtherThread(setDataThread st){
            otherThread = st;
        }
    }
    package thread;
    
    public class demoSynchorny {
    
        public static void main(String[] args) {
            setDataThread str;
            readDataThread rtr;
            str=new setDataThread();
            rtr=new readDataThread();
            str.setOtherThread(rtr);
            rtr.setOtherThread(str);
            str.start();
            rtr.start();
    
        }
    
    }

    输出结果如下:

    设置数据:295 count=1
    获得数据:295
    ......
    设置数据:974 count=99
    获得数据:974
    设置数据:526 count=100
    获得数据:526

    两个线程是严格交替运行的。

    7.暂停恢复和停止线程

    例7. 自己编写线程的暂停、恢复和停止方法。

    package thread;
    
    public class enhanceThread extends Thread {
        private static final int STOP = 1;
        private static final int RUNNING = 2;
        private static final int SUSPEND = 3;
        private int state = STOP;
        public synchronized void run(){
            int cnt = 0;
            while(state!=STOP){
                if(state==SUSPEND){
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                ++cnt;
                System.out.println("线程正在运行:"+cnt);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
        public void normalStop(){
            state = STOP;
        }
        
        public void normalSuspend(){
            state = SUSPEND;
        }
        
        //恢复线程运行
        public synchronized void normalResume(){
            state = RUNNING;
            notify();
        }
        
        public enhanceThread(){
            state = RUNNING;
        }
    }
    package thread;
    
    public class demoEhanceThread {
    
        public static void main(String[] args) {
            enhanceThread tr;
            tr = new enhanceThread();
            System.out.println("启动线程!");
            tr.start();
            try {
                Thread.sleep(1000);
                System.out.println("将线程挂起!");
                tr.normalSuspend();
                Thread.sleep(1000);
                System.out.println("恢复线程运行!");
                tr.normalResume();
                Thread.sleep(1000);
                System.out.println("终止线程运行!");
                tr.normalStop();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    }

    输出结果如下:

    启动线程!
    线程正在运行:1
    线程正在运行:2
    线程正在运行:3
    线程正在运行:4
    线程正在运行:5
    线程正在运行:6
    线程正在运行:7
    线程正在运行:8
    线程正在运行:9
    线程正在运行:10
    将线程挂起!
    恢复线程运行!
    线程正在运行:11
    线程正在运行:12
    线程正在运行:13
    线程正在运行:14
    线程正在运行:15
    线程正在运行:16
    线程正在运行:17
    线程正在运行:18
    线程正在运行:19
    线程正在运行:20
    终止线程运行!

    8.生产者-消费者问题实例

    例8. 生产者-消费者实例。

    package thread;
    
    public class common {
        private int production[]; //存放产品的缓冲区
        private int count;        //产品的实际数目
        private int BUFFERSIZE = 6; //缓冲区大小
        public common(){
            production = new int[BUFFERSIZE];
            count = 0;
        }
        //从缓冲区中取数据
        public synchronized int get(){
            int result;
            while(count<=0)
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            result = production[--count];
            notifyAll();
            return result;
        }
        //向缓冲区中写数据
        public synchronized void put(int newproduct){
            while(count>=BUFFERSIZE)
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            production[count++]=newproduct;
            notifyAll();
        }
    }
    package thread;
    //消费者线程
    public class consumer extends Thread {
        private common comm;
        public consumer(common mycomm){
            comm = mycomm;
        }
        
        public synchronized void run(){  //线程体
            int i,production;
            for(i=1;i<=20;i++){   //消费线程计数
                production = comm.get();
                System.out.println("得到的数据为:"+production);
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    package thread;
    //生产者线程
    public class producer extends Thread {
        private common comm;
        public producer(common mycomm){
            comm = mycomm;
        }
        
        public synchronized void run(){
            int i;
            for(i=1;i<=10;i++){
                comm.put(i);
                System.out.println("生产的数据为:"+i);
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    package thread;
    
    public class producer_consumer {
        public static void main(String[] args){
            common comm = new common();
            producer p1 = new producer(comm);
            producer p2 = new producer(comm);
            consumer c1 = new consumer(comm);
            p1.start();
            p2.start();
            c1.start();
        }
    }

    程序某次运行结果如下:

    生产的数据为:1
    得到的数据为:1
    生产的数据为:1
    得到的数据为:2
    生产的数据为:2
    生产的数据为:2
    生产的数据为:3
    得到的数据为:3
    生产的数据为:3
    生产的数据为:4
    得到的数据为:4
    生产的数据为:4
    生产的数据为:5
    得到的数据为:5
    生产的数据为:5
    得到的数据为:5
    生产的数据为:6
    生产的数据为:6
    得到的数据为:6
    生产的数据为:7
    生产的数据为:8
    得到的数据为:7
    得到的数据为:8
    生产的数据为:9
    生产的数据为:10
    得到的数据为:9
    得到的数据为:10
    生产的数据为:7
    得到的数据为:7
    生产的数据为:8
    得到的数据为:8
    生产的数据为:9
    得到的数据为:9
    生产的数据为:10
    得到的数据为:10
    得到的数据为:6
    得到的数据为:4
    得到的数据为:3
    得到的数据为:2
    得到的数据为:1

    结果表明,该程序已经很好地解决了生产者线程和消费者线程间的同步问题。

  • 相关阅读:
    Params参数的应用
    用反射动态创建委托
    Javascript中的Array的运用
    四个JS代码与jquery架构简单运用
    base 基本用法转载自(MSDN)
    Microsoft AJAX Library 新特性简单代码
    典型的委托的不同写法(转载)
    创建反射实例|反射过滤|反射搜索
    【软工】第1次个人作业
    【软工】第0次个人作业
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4234211.html
Copyright © 2011-2022 走看看