zoukankan      html  css  js  c++  java
  • 初探Java多线程

    多线程是由Java提出的概念,那么什么是线程呢?这里会涉及到几个名字听着很类似的东西:程序、线程、进程。

    程序:存储在磁盘上的一系列的文件,包括可执行文件和不可执行文件。

    进程:在内存中,每一个程序都会开启一个进程。

    线程:线程是进程的最小执行单元,线程在寄存器中,每一个线程需要消耗一定的cpu资源和512k到1M的内存资源。

    多线程:也就是同一个程序中开启多个线程就是多线程。

    使用多线程有什么样的优势呢?我们都知道在Java中,代码是一句一句地往下执行的,上面的代码没有执行完毕,下面的另一段代码就必须要等到上面的执行完毕,它才能够执行。如果有程序要求必须在同一时间执行不同的代码的话,单线程就显然无法满足要求了。另外由于多线程是几个线程一同执行,所以可以大大的缩短一些需要大量重复执行的代码的执行时间,打个比方,有一斤米要知道它有多少粒,如果一个人去数的话,不知道要数到什么时候。但是如果多派几个人去数的话,就能够极大的提高效率,节约时间。现实生活是这个样子,程序的执行更加如此。试问如果一个程序要得出结果需要个半分钟,你还愿意去等吗?别说半分钟了,几秒钟都不一定想等。所以多线程的作用就在于此了。多线程能够提高程序的运行速度和执行效率,能够同时执行一段代码,完成单线程无法完成的事情。当然事情都是双面性的,线程有其优点,自然也会有缺陷。前面已经说过线程是要消耗CPU和内存资源的,CPU和内存的资源是有限的。假设这样的一种情况,有好几个线程都要使用CPU,这时应该怎么办呢(线程的异步)。解决方法当然有让先拿到CPU的a线程先执行,其他的线程等待,a线程执行完毕后,释放资源,然后其他的线程再次使用(线程的同步)。但是这样又会产生新的问题,如果a线程和b线程同时执行了,a线程需要等待b线程的资源释放才能够继续,而b线程同样需要a线程的资源释放才能够继续,这样就会陷入一个死回路中,谁也出不来(线程的死锁)。当然我们并不会因为线程有缺陷就不用它,正相反线程的优势是我们需要的,我们当然要用线程。

    线程的使用有两种方法:

    继承Thread类:Thread类实现了Runnable接口。常用的方法有:run()线程需要完成的事情放在run方法中;sleep()让线程休眠的方法,参数是毫秒数;start()启动线程的方法,然后start会执行run方法。

    实现Runnable接口:run()线程需要完成的事情。

    需要注意的是:Runnable接口中只有一个抽象的run()方法,它是没有启动线程的方法的,所以实现Runnable接口的类要想启动线程,必须要实例化一个Thread对象,通过调用Thread对象的start方法才能够正常的启动一个线程。不知道大家有没有这样的疑惑:那就是为什么需要调用start方法类启动一个线程,直接调用run方法不行吗?要解释这个问题还需要搞清楚一件事情:那就是如果一个程序没有使用线程,那么这个程序中会不会存在线程。看下面的代码:

    public class Test {
    
        public static void main(String[] args) {
            System.out.println("main方法执行了");
            System.out.println(Thread.currentThread());
        }
    }

    这段代码输出结果是这样的:

    main方法执行了
    Thread[main,5,main]

    这说明了什么,只要我们程序中存在main方法,那么该程序必然会存在一个线程。也就是说Java的虚拟机会自动为main方法启动一个线程。在Java中的线程是由Java的虚拟机来调度的,我们自己是无法启动线程的,所以需要一个start方法来告诉虚拟机我们要启动一个线程。换句话说,直接调用run方法,就是直接调用了run方法而已,是并没有启动线程的。

    下面举一个多线程的例子:

    package com.cbs;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.util.Random;
    
    import javax.swing.JFrame;
    /**
     * 线程类,画小球
     * @author CBS
     */
    public class ThreadDemo extends Thread {
    
        private Graphics g;
        private JFrame frame = null;
    
        public ThreadDemo() {
    
        }
    
        public Graphics getG() {
            return g;
        }
    
        public void setG(Graphics g) {
            this.g = g;
        }
    
        public JFrame getFrame() {
            return frame;
        }
    
        public void setFrame(JFrame frame) {
            this.frame = frame;
        }
    
        public ThreadDemo(JFrame frame, Graphics g) {
            this.frame = frame;
            this.g = g;
            System.out.println(frame);
        }
    
        Random r = new Random();
        //随机颜色
        Color color = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
    
        public void run() {
            Graphics2D g2d = (Graphics2D) g;
    //        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    //                RenderingHints.VALUE_ANTIALIAS_ON);
    //        
            int speedx = 3;//小球的移动速度
            int speedy = 3;
            int x = r.nextInt(frame.getWidth());
            int y = r.nextInt(frame.getHeight());
            while (true) {
                if (x < frame.getWidth() && y < frame.getHeight()) {
                    g2d.setColor(Color.WHITE);
                    g2d.fillOval(x, y, 30, 30);
                    x += speedx;
                    y += speedy;
                    //判断是否碰到边界,如果是把小球反弹。
                    if (x > frame.getWidth()-20 && speedx > 0) {
                        speedx = -speedx;
                    } else if (x < 10 && speedx < 0)
                        speedx = -speedx;
                    if (y >frame.getHeight()-20 && speedy > 0)
                        speedy = -speedy;
                    else if (y < 30 && speedy < 0)
                        speedy = -speedy;
    
                    g2d.setColor(Color.GREEN);
                    g2d.fillOval(x, y, 30, 30);
                }
                try {
                    //线程休眠
                    this.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
        }
    
    }
    
    package com.cbs;
    /**
     * 主类,用来初始化一个界面
     */
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.util.Random;
    
    import javax.swing.JFrame;
    
    public class Draw  {
        
        public static void main(String[] args) {
            Draw d=new Draw();
            d.showUI();
        }
        
        public void showUI(){
            JFrame jf=new JFrame();
            jf.setTitle("Moving Point");
            jf.setSize(500,500);
            jf.setDefaultCloseOperation(3);
            jf.setLocationRelativeTo(null);
            jf.getContentPane().setBackground(Color.WHITE);
            
            
            jf.setVisible(true);
            
            
            Graphics g=jf.getGraphics();
            
            Random r=new Random();
            //随机启动多个线程
            for(int i=0;i<=r.nextInt(10);i++){
                ThreadDemo t=new ThreadDemo();
                t.setFrame(jf);
                t.setG(g);
                t.start();
            }
        }
        
    }
    View Code

    运行后就是几个球在界面上到处乱撞。

    ps:有点小bug ,我还不懂怎么回事。

  • 相关阅读:
    灾后重建
    购物
    [BZOJ3991][SDOI2015]寻宝游戏
    [BZOJ2286][SDOI2011]消耗战
    [Luogu4149][IOI2011]Race
    [BZOJ4003][JLOI2015]城池攻占
    [HDU5765]Bonds
    [HDU5977]Garden of Eden
    [Luogu4331][Baltic2004]数字序列
    [BZOJ4540][HNOI2016]序列
  • 原文地址:https://www.cnblogs.com/cbs-writing/p/7238430.html
Copyright © 2011-2022 走看看