zoukankan      html  css  js  c++  java
  • Runable和Thread

    Java多线程

    java中有两种实现多线程的方式: 
    1. 一种是通过继承Thread类,同时重写run()方法。但是java中,只允许单继承,也就是一个类只能继承一个父类,使得该方式具有一定的局限性,等下就知道了。 
    2. 另一种是实现Runnable类接口的run()方法,再结合Thread类来实现多线程。 
    两种方式最终都是通过调用start()方法来实现多线程。切记不能直接调用Thread类或Runnable对象的run()方法,因为直接调用run()方法,只会执行同一个线程中的任务,而不会启动新线程。调用start()方法将会创建一个

    例1:继承Thread类,调用run()方法

    public class MyThread extends Thread {
    
        private String name;
        private int ticket = 5;
        public MyThread(String name) {
            this.name = name;
        }
    
        public void run() {
            for (int i=0; i<10; i++) {
                if (this.ticket>0)
                    System.out.println("线程开始:"+this.name+",卖票:i="+this.ticket--);
            }
        }
    }
    
    //TestThreadRunnable.java:调用run()方法
    public class TestThreadRunnable {
    
        public static void main(String [] args) {
    
            Thread t1 = new MyThread("线程a");
            Thread t2 = new MyThread("线程b");
    
            **t1.run()**;
            **t2.run()**;
            /*
            Runnable r = new MyRunnable();
    
            Thread t1 = new Thread(r, "线程a");
            Thread t2 = new Thread(r, "线程b");
    
            t1.start();
            t2.start();
            */
        }
    
    }
    

      运行结果

    线程开始:线程a,卖票:i=5
    线程开始:线程a,卖票:i=4
    线程开始:线程a,卖票:i=3
    线程开始:线程a,卖票:i=2
    线程开始:线程a,卖票:i=1
    线程开始:线程b,卖票:i=5
    线程开始:线程b,卖票:i=4
    线程开始:线程b,卖票:i=3
    线程开始:线程b,卖票:i=2
    线程开始:线程b,卖票:i=1

    一、扩展java.lang.Thread类

    复制代码
    public class Main {
    
        public static void main(String[] args) {
            MyThread T1 = new MyThread("A");
            MyThread T2 = new MyThread("B");
            T1.start();
            T2.start();
    
    
        }
    
    }
    
     class MyThread extends Thread {
        private String name;
        public MyThread(String name) {
            this.name = name;
        }
        
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println(name+":"+i);
                try {
                    sleep(1000); //休眠1秒,避免太快导致看不到同时执行
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
        }
    }
    复制代码

    输出:

    A:0
    B:0
    A:1
    B:1
    B:2
    A:2
    B:3
    A:3
    A:4
    B:4

    程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。随着调用MitiSay的两个对象的start方法,另外两个线程也启动了,这样,整个应用就在多线程下运行。
     
    注意:start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的。
    从程序运行的结果可以发现,多线程程序是乱序执行。因此,只有乱序执行的代码才有必要设计为多线程。
    Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会。
    实际上所有的多线程代码执行顺序都是不确定的,每次执行的结果都是随机的。(要看效果要去除sleep方法,然后加大打印次数)

    二、实现java.lang.Runnable接口

    如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

    public class Main {
     
        public static void main(String[] args) {
     
            //测试Runnable
            MyThread1 t1 = new MyThread1();
            new Thread(t1).start();//同一个t1,如果在Thread中就不行,会报错
            new Thread(t1).start();
            new Thread(t1).start();
     
        }
     
    }
    class MyThread1 implements Runnable{
        private int ticket = 10;
        @Override
        //记得要资源公共,要在run方法之前加上synchronized关键字,要不然会出现抢资源的情况
        public synchronized  void  run() {
            for (int i = 0; i <10; i++) {
                if (this.ticket>0) {
                    System.out.println("卖票:ticket"+this.ticket--);
                }
            }
            
        }
        
    }
     

    输出:

    卖票:ticket10
    卖票:ticket9
    卖票:ticket8
    卖票:ticket7
    卖票:ticket6
    卖票:ticket5
    卖票:ticket4
    卖票:ticket3
    卖票:ticket2
    卖票:ticket1

    这里要注意每个线程都是用同一个实例化对象,如果不是同一个,效果就和上面的一样了!

     

    总结:

    实现Runnable接口比继承Thread类所具有的优势:

    1):适合多个相同的程序代码的线程去处理同一个资源

    2):可以避免java中的单继承的限制

    3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

  • 相关阅读:
    【leetcode】Binary Search Tree Iterator
    【leetcode】Palindrome Partitioning II
    【leetcode】Best Time to Buy and Sell Stock III
    【leetcode】Best Time to Buy and Sell Stock II
    【leetcode】Longest Consecutive Sequence
    【leetcode】Factorial Trailing Zeroes
    【leetcode】Simplify Path
    【leetcode】Generate Parentheses
    【leetcode】Combination Sum II
    【leetcode】Combination Sum
  • 原文地址:https://www.cnblogs.com/cjjjj/p/6805414.html
Copyright © 2011-2022 走看看