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

      Java 虚拟机允许应用程序并发地运行多个执行线程。
     
    在Java中,多线程的实现有两种方式:
    扩展java.lang.Thread类
    实现java.lang.Runnable接口
     
     
      每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
     
      当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
     
      调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
      非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
    public class TestMitiThread {
        public static void main(String[] rags) {
            System.out.println(Thread.currentThread().getName() + " 线程运行开始!");
            new MitiSay("A").start();
            new MitiSay("B").start();
            System.out.println(Thread.currentThread().getName() + " 线程运行结束!");
        }
    }
     
    class MitiSay extends Thread {
        public MitiSay(String threadName) {
            super(threadName);
        }
     
        public void run() {
            System.out.println(getName() + " 线程运行开始!");
            for (int i = 0; i < 10; i++) {
                System.out.println(i + " " + getName());
                try {
                    sleep((int) Math.random() * 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(getName() + " 线程运行结束!");
        }
    }
    
    运行结果:
     
    main 线程运行开始!
    main 线程运行结束!
    A 线程运行开始!
    0 A
    1 A
    B 线程运行开始!
    2 A
    0 B
    3 A
    4 A
    1 B
    5 A
    6 A
    7 A
    8 A
    9 A
    A 线程运行结束!
    2 B
    3 B
    4 B
    5 B
    6 B
    7 B
    8 B
    9 B
    B 线程运行结束!
     
    
    说明:
    程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。随着调用MitiSay的两个对象的start方法,另外两个线程也启动了,这样,整个应用就在多线程下运行。
     
    在一个方法中调用Thread.currentThread().getName()方法,可以获取当前线程的名字。在mian方法中调用该方法,获取的是主线程的名字。
     
    注意:start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的。
    从程序运行的结果可以发现,多线程程序是乱序执行。因此,只有乱序执行的代码才有必要设计为多线程。
    Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会。
    实际上所有的多线程代码执行顺序都是不确定的,每次执行的结果都是随机的。
     实现java.lang.Runnable接口
    public class TestMitiThread1 implements Runnable {
     
        public static void main(String[] args) {
            System.out.println(Thread.currentThread().getName() + " 线程运行开始!");
            TestMitiThread1 test = new TestMitiThread1();
            Thread thread1 = new Thread(test);
            Thread thread2 = new Thread(test);
            thread1.start();
            thread2.start();
            System.out.println(Thread.currentThread().getName() + " 线程运行结束!");
        }
     
        public void run() {
            System.out.println(Thread.currentThread().getName() + " 线程运行开始!");
            for (int i = 0; i < 10; i++) {
                System.out.println(i + " " + Thread.currentThread().getName());
                try {
                    Thread.sleep((int) Math.random() * 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " 线程运行结束!");
        }
    }
     
    
    运行结果:
     
    main 线程运行开始!
    Thread-0 线程运行开始!
    main 线程运行结束!
    0 Thread-0
    Thread-1 线程运行开始!
    0 Thread-1
    1 Thread-1
    1 Thread-0
    2 Thread-0
    2 Thread-1
    3 Thread-0
    3 Thread-1
    4 Thread-0
    4 Thread-1
    5 Thread-0
    6 Thread-0
    5 Thread-1
    7 Thread-0
    8 Thread-0
    6 Thread-1
    9 Thread-0
    7 Thread-1
    Thread-0 线程运行结束!
    8 Thread-1
    9 Thread-1
    Thread-1 线程运行结束!
     
    
    说明:
    TestMitiThread1类通过实现Runnable接口,使得该类有了多线程类的特征。run()方法是多线程程序的一个约定。所有的多线程代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。
    在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。
    实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是扩展Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程编程的基础。
     
  • 相关阅读:
    LeetCode 242. Valid Anagram (验证变位词)
    LeetCode 205. Isomorphic Strings (同构字符串)
    LeetCode 204. Count Primes (质数的个数)
    LeetCode 202. Happy Number (快乐数字)
    LeetCode 170. Two Sum III
    LeetCode 136. Single Number (落单的数)
    LeetCode 697. Degree of an Array (数组的度)
    LeetCode 695. Max Area of Island (岛的最大区域)
    Spark中的键值对操作
    各种排序算法总结
  • 原文地址:https://www.cnblogs.com/houjiie/p/6127233.html
Copyright © 2011-2022 走看看