zoukankan      html  css  js  c++  java
  • Java学习手记2——多线程

    一.线程的概念

    CPU执行程序,就好比一个人在干事情一样,同一个时间你只能做一件事情,但是这样的效率实在是太低了,在你用电脑的时候,听歌就不能浏览网页,看电影就不能下载视频,你想想是不是很蛋疼。

    所以为了解决这个问题,CPU设计成了分时处理的方式,即不同的时间CPU做不同的事情,这样就大大提高了效率,能这样做的原因是因为CPU相对于人的接收信息的速度,快得多!也就是说,你边听歌边浏览网页,看上去好像音乐播放器和浏览器两个程序在同时工作,其实他们是分时在工作,即播放器工作一会,浏览器工作一会,这样交叉执行的,只不过是你接受信息的速度很慢,所以感觉不到而已。

    那么多线程,和多个程序是一样的道理,多线程是一个程序内部的多个子任务分时执行。比如:qq的视频聊天,你可以边看视频,边发消息,这就是两个线程。

    PS:另外,好多人解释进程和线程的区别,用一大堆抽象的概念,说的跟没说一样,晦涩难懂,在我看来,进程和线程都是运行着的程序,只不过进程是运行着的独立的程序(比如:QQ,LOL,QQ影音),而线程是一个独立的程序里面的运行着的子程序(比如:QQ里的首发消息,收发加播放视频,上下载文件等),如果把线程抽离出来,也是一个进程。之所以拿这两个比较,还有一个原因是他们的另外一个共同点:都是分时执行的。即进程是不同程序的分时执行(比如用QQ的同时可以玩LOL),而线程是一个程序内部多个子程序的分时执行(比如用QQ聊天的时候可以接受并播放对方摄像头传过来的视频,同时还可以上下载文件)。

    二.Java中的线程的实现方式

    在Java中,实现多线程有两种方式:

    1.继承 Thread类

    细节:继承Thread类之后,重写run()方法,把要实现多线程的代码敲进run()方法里,然后在main函数中实例化这个类(即之前继承并重写run()方法的类)的对象,并调用继承的start()方法,从该方法调用的地方开始,CPU便会利用空闲时间段执行run()里的程序代码。

     1 import java.lang.*;
     2 public class TestThread extends Thread{
     3     
     4     public void run(){
     5         System.out.println(Thread.currentThread().getName());
     6     }
     7     
     8     
     9     public static void main(String[] args) {
    10         Thread tt = new TestThread();
    11         tt.start();//这里启动了另一个线程
    12         System.out.println(Thread.currentThread().getName());
    13     }
    14 
    15 }

    运行结果:

    main
    Thread-0

    2.实现Runable接口

    细节:Thread这个类,构造方法有两个:Thread()和Thread(Runnable target)。

    这里介绍第二个构造方法Thread(Runable target),这个Runnable是一个接口,接口里面定义了一个run()方法,可以将一个类引用这个接口,实现其中的run()方法,将需要多线程执行的代码放入run()方法中,然后用第二个构造方法调用这个实现了Runnable接口的类。不得不说接口是个神器

     1 import java.lang.*;
     2 public class TestThread implements Runnable{
     3     
     4     public void run(){
     5         System.out.println(Thread.currentThread().getName());
     6     }
     7     
     8     
     9     public static void main(String[] args) {
    10         Thread tt = new Thread(new TestThread());
    11         tt.start();
    12         System.out.println(Thread.currentThread().getName());
    13     }
    14 
    15 }

    运行结果:

    main
    Thread-0

    3.这两种方式的区别

    • Java中的类只能是单继承,所以当一个类已经是继承别个类的子类,又要加入多线程,就要用第二种实现Runnable接口的方法
    • 由于两者构造方式不同,第一种方式每次都是新建对象来实现多线程,而第二种方式可以使多个线程共享一个对象(实现了Runnable接口的类的对象)的资源,可以根据情况来使用。

    例如:模拟一个售票的过程,一共有一百张票,三个人分别售票。

     1 import java.lang.*;
     2 public class TestThread implements Runnable{
     3     private int num = 100;
     4     public void run(){
     5         while(num-->=0)
     6         System.out.println(Thread.currentThread().getName()+':'+num);
     7         return;
     8     }
     9     
    10     
    11     public static void main(String[] args) {
    12         TextThread tt = new TestThread();
    13         new Thread(tt).start();
    14         new Thread(tt).start();
    15         new Thread(tt).start();
    16         System.out.println(Thread.currentThread().getName());
    17     }
    18 
    19 }

    运行部分结果:

    Thread-2:91
    Thread-2:90
    Thread-2:89
    Thread-2:88
    Thread-2:87
    Thread-1:86
    Thread-1:84
    Thread-1:83

    三.Thread类中一些其他的方法

     static Thread curruntThread() 返回当前正在执行的线程对象的引用

    String getName() 返回该线程名称

    void join() 在当前位置插入该线程

    void join(long millis) 在当前位置插入该线程执行millis毫秒,继续之前的线程

    2016-08-26 01:16:19

  • 相关阅读:
    基于DPDK的高效包处理系统
    Docker在centos系统上的安装
    TCP三次握手
    service与kube-proxy
    路由策略和策略路由
    golang context 超时自动取消方法
    用Dockerfile构建镜像
    kubemark模拟k8s计算节点,测试k8s组件性能
    golang动画等待计算菲波那契结果
    golang实现的倒计时计数器
  • 原文地址:https://www.cnblogs.com/jizhji/p/5808836.html
Copyright © 2011-2022 走看看