zoukankan      html  css  js  c++  java
  • Java多线程理解

    一、理论概念

    进程与线程

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。

    线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

    进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

    二、线程的Java实现

    目前实现java线程有2种方式,继承Thread类和实现Runnable接口,重写run方法。

    1、实现Runnable接口

    实现 Runnable的接口的好处是实现变量的共享,多个线程使用同一个Runable对象,如上代码块中的成员变量j:

    package src;
    
    /**
     * 
     * @author Shawn Wang
     * 
     */
    public class MyThread implements Runnable {
        private int j = 100;
    
        @Override
        public void run() {
            while (true) {
                if (j > 0) {
                    System.out.println(Thread.currentThread().getName() + "-- num:"
                            + j--);
                } else {
                    break;
                }
            }
        }
    
        public static void main(String[] args) {
            MyThread mt = new MyThread();
            Thread thread1 = new Thread(mt);
            Thread thread2 = new Thread(mt);
            Thread thread3 = new Thread(mt);
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    View Code

    输出结果:

    Thread-1-- num:100
    Thread-3-- num:98
    Thread-2-- num:99
    Thread-2-- num:95
    Thread-3-- num:96
    Thread-1-- num:97
    Thread-1-- num:92
    Thread-1-- num:91
    Thread-3-- num:93
    Thread-3-- num:89
    Thread-3-- num:88
    Thread-2-- num:94
    Thread-2-- num:86
    Thread-2-- num:85
    Thread-2-- num:84
    Thread-3-- num:87
    Thread-3-- num:82
    Thread-1-- num:90
    Thread-1-- num:80
    Thread-3-- num:81
    Thread-3-- num:78
    Thread-3-- num:77
    Thread-3-- num:76
    Thread-3-- num:75
    Thread-3-- num:74
    Thread-2-- num:83
    Thread-2-- num:72
    Thread-2-- num:71
    Thread-2-- num:70
    Thread-3-- num:73
    Thread-1-- num:79
    Thread-3-- num:68
    Thread-3-- num:66
    Thread-3-- num:65
    Thread-2-- num:69
    Thread-2-- num:63
    Thread-2-- num:62
    Thread-2-- num:61
    Thread-2-- num:60
    Thread-2-- num:59
    Thread-2-- num:58
    Thread-2-- num:57
    Thread-2-- num:56
    Thread-2-- num:55
    Thread-2-- num:54
    Thread-2-- num:53
    Thread-2-- num:52
    Thread-3-- num:64
    Thread-1-- num:67
    Thread-3-- num:50
    Thread-2-- num:51
    Thread-3-- num:48
    Thread-1-- num:49
    Thread-3-- num:46
    Thread-2-- num:47
    Thread-3-- num:44
    Thread-1-- num:45
    Thread-3-- num:42
    Thread-2-- num:43
    Thread-3-- num:40
    Thread-1-- num:41
    Thread-3-- num:38
    Thread-2-- num:39
    Thread-3-- num:36
    Thread-1-- num:37
    Thread-3-- num:34
    Thread-2-- num:35
    Thread-3-- num:32
    Thread-1-- num:33
    Thread-3-- num:30
    Thread-2-- num:31
    Thread-3-- num:28
    Thread-1-- num:29
    Thread-3-- num:26
    Thread-2-- num:27
    Thread-3-- num:24
    Thread-1-- num:25
    Thread-3-- num:22
    Thread-2-- num:23
    Thread-3-- num:20
    Thread-1-- num:21
    Thread-3-- num:18
    Thread-2-- num:19
    Thread-3-- num:16
    Thread-1-- num:17
    Thread-3-- num:14
    Thread-2-- num:15
    Thread-3-- num:12
    Thread-1-- num:13
    Thread-3-- num:10
    Thread-2-- num:11
    Thread-3-- num:8
    Thread-1-- num:9
    Thread-3-- num:6
    Thread-2-- num:7
    Thread-3-- num:4
    Thread-1-- num:5
    Thread-3-- num:2
    Thread-2-- num:3
    Thread-1-- num:1
    result

    2、继承Thread类

    package src;
    
    public class ThreadClient extends Thread {
    
        public ThreadClient(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for (int i = 0; i <= 10; i++) {
                System.out.println(currentThread().getName() + ":" + i);
            }
        }
       
        public static void main(String[] args) {
            ThreadClient thread1 = new ThreadClient("thread1");
            ThreadClient thread2 = new ThreadClient("thread1");
            ThreadClient thread3 = new ThreadClient("thread1");
            thread1.start();
            thread2.start();
            thread3.start();
        }
    
    }
    View Code

    输出结果

    thread1:0
    thread1:1
    thread1:0
    thread1:1
    thread1:0
    thread1:1
    thread1:2
    thread1:3
    thread1:4
    thread1:5
    thread1:6
    thread1:2
    thread1:2
    thread1:3
    thread1:4
    thread1:3
    thread1:4
    thread1:5
    thread1:6
    thread1:7
    thread1:7
    thread1:8
    thread1:9
    thread1:10
    thread1:5
    thread1:6
    thread1:7
    thread1:8
    thread1:9
    thread1:8
    thread1:9
    thread1:10
    thread1:10
    result

    疑问:

    为什么要重写 run方法?

    run方法时存储线程所要运行的代码,不能在直接调用run方法,需要通过start方法来调用。

    三、线程同步

    场景:如果线程进行了sleep 操作时,其他线程对共享变量做了改变,会造成数据不同步问题。

    package src;
    
    /**
     * 
     * @author Shawn Wang
     * 
     */
    public class MyThread implements Runnable {
        private int j = 100;
    
        @Override
        public void run() {
            while (true) {
                if (j > 0) {
                    try {
                        Thread.sleep(1000);// 当前线程休眠1秒
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "-- num:"
                            + j--);
                } else {
                    break;
                }
            }
        }
    
        public static void main(String[] args) {
            MyThread mt = new MyThread();
            Thread thread1 = new Thread(mt);
            Thread thread2 = new Thread(mt);
            Thread thread3 = new Thread(mt);
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    View Code

    输出结果:

    Thread-1-- num:100
    Thread-2-- num:99
    Thread-3-- num:98
    Thread-1-- num:97
    Thread-3-- num:95
    Thread-2-- num:96
    Thread-1-- num:94
    Thread-2-- num:92
    Thread-3-- num:93
    Thread-3-- num:91
    Thread-2-- num:90
    Thread-1-- num:90
    Thread-3-- num:89
    Thread-2-- num:88
    Thread-1-- num:87
    Thread-3-- num:86
    Thread-2-- num:85
    Thread-1-- num:85
    Thread-3-- num:84
    Thread-2-- num:83
    Thread-1-- num:82
    Thread-3-- num:81
    Thread-1-- num:80
    Thread-2-- num:80
    Thread-3-- num:79
    Thread-2-- num:77
    Thread-1-- num:78
    Thread-3-- num:76
    Thread-2-- num:75
    Thread-1-- num:74
    Thread-2-- num:73
    Thread-3-- num:71
    Thread-1-- num:72
    Thread-2-- num:70
    Thread-1-- num:69
    Thread-3-- num:69
    Thread-2-- num:68
    Thread-3-- num:66
    Thread-1-- num:67
    Thread-2-- num:65
    Thread-1-- num:64
    Thread-3-- num:64
    Thread-2-- num:63
    Thread-1-- num:62
    Thread-3-- num:61
    Thread-2-- num:60
    Thread-3-- num:58
    Thread-1-- num:59
    Thread-2-- num:57
    Thread-1-- num:56
    Thread-3-- num:56
    Thread-2-- num:55
    Thread-1-- num:54
    Thread-3-- num:54
    Thread-2-- num:53
    Thread-3-- num:52
    Thread-1-- num:52
    Thread-3-- num:51
    Thread-2-- num:50
    Thread-1-- num:51
    Thread-3-- num:49
    Thread-1-- num:48
    Thread-2-- num:48
    Thread-3-- num:47
    Thread-1-- num:46
    Thread-2-- num:45
    Thread-1-- num:44
    Thread-2-- num:42
    Thread-3-- num:43
    Thread-3-- num:40
    Thread-1-- num:39
    Thread-2-- num:41
    Thread-2-- num:38
    Thread-3-- num:37
    Thread-1-- num:38
    Thread-1-- num:36
    Thread-2-- num:35
    Thread-3-- num:36
    Thread-1-- num:34
    Thread-2-- num:33
    Thread-3-- num:33
    Thread-1-- num:32
    Thread-3-- num:30
    Thread-2-- num:31
    Thread-1-- num:29
    Thread-3-- num:29
    Thread-2-- num:29
    Thread-3-- num:28
    Thread-1-- num:28
    Thread-2-- num:28
    Thread-1-- num:27
    Thread-2-- num:26
    Thread-3-- num:27
    Thread-1-- num:25
    Thread-2-- num:24
    Thread-3-- num:24
    Thread-1-- num:23
    Thread-3-- num:22
    Thread-2-- num:22
    Thread-1-- num:21
    Thread-3-- num:20
    Thread-2-- num:20
    Thread-1-- num:19
    Thread-3-- num:18
    Thread-2-- num:17
    Thread-3-- num:16
    Thread-1-- num:15
    Thread-2-- num:14
    Thread-2-- num:13
    Thread-3-- num:12
    Thread-1-- num:13
    Thread-2-- num:11
    Thread-1-- num:10
    Thread-3-- num:10
    Thread-2-- num:9
    Thread-1-- num:7
    Thread-3-- num:8
    Thread-2-- num:6
    Thread-3-- num:5
    Thread-1-- num:5
    Thread-2-- num:4
    Thread-3-- num:3
    Thread-1-- num:2
    Thread-2-- num:1
    Thread-1-- num:0
    Thread-3-- num:-1
    result

    出现了负数。

    解决加上同步锁synchronized

    同步代码块的格式:
        synchronized(对象){
               需要被同步的代码;
        } 

    package src;
    
    /**
     * 
     * @author Shawn Wang
     * 
     */
    public class MyThread implements Runnable {
        private int j = 100;
    
        @Override
        public void run() {
            while (true) {
                synchronized (this) {
                    if (j > 0) {
                        try {
                            Thread.sleep(1000);// 当前线程休眠1秒
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()
                                + "-- num:" + j--);
                    } else {
                        break;
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            MyThread mt = new MyThread();
            Thread thread1 = new Thread(mt);
            Thread thread2 = new Thread(mt);
            Thread thread3 = new Thread(mt);
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    View Code
  • 相关阅读:
    SpringMVC视图解析器
    FreeMarker介绍
    一篇很全面的freemarker教程
    request,session,application
    nav布局 在线演示 DIVCSS5
    opacity
    java 某字符串在另一字符串中是否存在
    bochs 使用讲解
    使用VS2015搭建Lua开发环境
    Zip文件格式
  • 原文地址:https://www.cnblogs.com/shawnblogs/p/4817161.html
Copyright © 2011-2022 走看看