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

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

  • 相关阅读:
    Java实现各种内部排序算法
    Java实现堆排序(大根堆)
    Java对象的序列化和反序列化
    Java实现链式存储的二叉查找树(递归方法)
    337. House Robber III(包含I和II)
    318. Maximum Product of Word Lengths
    114. Flatten Binary Tree to Linked List
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    96. Unique Binary Search Trees(I 和 II)
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4234211.html
Copyright © 2011-2022 走看看