zoukankan      html  css  js  c++  java
  • 多线程实例

    多线程的概念在此就不多说了,打个通熟易懂比方,把自己看做一个进程,做的每件事都看做为线程,自己可以同时玩魔兽和听歌,那么玩魔兽和听歌就是两个线程,为多线程。
        java是少数集中支持多线程的语言之一,大多数的语言只能运行一个程序块,无法同时运行不同的程序块,而java则弥补了这个缺陷。
        举个公司项目开发遇到的一个简单例子,用户上传压缩文件到服务器后,要对该压缩包进行两个操作,一是将该压缩包复制到指定目录,一是将该压缩包解压到另一指定目录,最终响应用户提示文件上传成功。如果压缩包很大的话,上传后进行的复制和解压功能也会占用很长时间,用户就会等待很长的时间。其实复制和解压的功能和用户操作没有直接关系,完全可以独立出来,其解决的思路如下:
        当用户上传压缩文件完毕之后,我们立即创建两个线程,一是复制压缩文件的线程;二是解压压缩文件的线程。我们可以通过线程的构造方法把文件的信息传递给相应的线程,当我们启动两线程的start方法后,我们就不必再关心其复制和解压的操作,而是直接响应用户,这样用户明显感觉操作变快,而复制和解压的操作仍在后台偷偷的进行着。

        实现多线程的方法有两个,一是继承Thread,二是实现接口Runnable。二者的区别不多说,继承只能单继承,而接口可以实现多个,故本人更倾向使用后者。

    下面把代码模型贴出来,供大家参考参考:

    import java.io.File; 
    
    public class FileOperate { 
        public static void main(String[] args) { 
            Long begin = System.currentTimeMillis(); 
     
            // 上传文件 
            UploadFile uploadFile = new UploadFile(); 
            File file = uploadFile.uploadFileMethod(); 
            // 给线程传递参数 
            CoppyFile coppyFile = new CoppyFile(file); 
            UnZipFile unZipFile = new UnZipFile(file); 
            // 创建线程 
            Thread coppyThread = new Thread(coppyFile); 
            Thread unZipThread = new Thread(unZipFile); 
            // 启动线程 
            coppyThread.start(); 
            unZipThread.start(); 
     
            Long end = System.currentTimeMillis(); 
            // 响应用户请求 
            System.out.println("恭喜,文件上传成功,耗时:" + (end - begin) + "毫秒"); 
        } 
    } 
     
    /**
     * 上传文件类
     * 
     */ 
    class UploadFile { 
        // 文件上传 
        public File uploadFileMethod() { 
            File file = new File("filePath"); 
            System.out.println("文件上传完毕"); 
            return file; 
        } 
    } 
     
    /**
     * 复制文件类
     * 
     */ 
    class CoppyFile implements Runnable { 
        private File file; 
     
        public CoppyFile(File file) { 
            this.file = file; 
        } 
     
        @Override 
        public void run() { 
            coppyFileMethod(file); 
        } 
     
        // 文件复制 
        public void coppyFileMethod(File file) { 
            // 睡眠15秒钟 
            try { 
                Thread.sleep(15000); 
            } catch (InterruptedException e) { 
                e.printStackTrace(); 
            } 
            System.out.println("文件复制完毕"); 
        } 
    } 
     
    /**
     * 解压文件类
     * 
     */ 
    class UnZipFile implements Runnable { 
        private File file; 
     
        public UnZipFile(File file) { 
            this.file = file; 
        } 
     
        @Override 
        public void run() { 
            unZipFileMethod(file); 
     
        } 
     
        // 文件解压 
        public void unZipFileMethod(File file) { 
            // 睡眠10秒钟 
            try { 
                Thread.sleep(10000); 
            } catch (InterruptedException e) { 
                e.printStackTrace(); 
            } 
            System.out.println("文件解压完毕"); 
        } 
    } 

    在此说明一个问题:

    线程的run()与start()的区别:
    执行run()方法方法是简单的方法调用,而不在重新启动一个线程。
    而执行start()方法,才是将待执行的方法放入线程池中,等待抢锁,再执行。
    故,我们在使用implements Runnable来实现一个线程类时,需要使用new Thread(t).start()来启动线程,而非直接调用run()方法。
    (可以通过程序调试来看出端倪。)

    <引:http://www.2cto.com/kf/201207/139100.html>

  • 相关阅读:
    在指定文件夹目录下打开jupyter notebook
    防止sql注入
    惰性函数——适合外层函数只需要执行一次
    Text类型
    怎样理解阻塞非阻塞与同步异步的区别?
    Element类型
    避免使用eval()
    javascript 连等赋值问题
    类数组转化为数组
    DOM10-1节点层次
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/4110747.html
Copyright © 2011-2022 走看看