多线程学习笔记2 - 实现自己的线程

进入正题前先了解两个名词,进程线程

 

进程:可以理解为一个应用程序,具有独立的存储空间。

 

线程:可称之为轻量级进程,占用资源小存在于进程中。所有线程共享进程公共内存。

 

总之进程和线程是(可以帮你完成某项任务的)两种基本单元。Java并发编程主要还是从线程出发。

 

什么是多线程

每个Java应用中都至少包含一个线程(main线程)。程序中的多个线程是“同时”被操作,从而提高运行效率的。对于单核CPU来说“同时”只是假象,在同一时间点有且仅有一个线程可以被执行。操作系统通过切分CPU时间,使得不同的线程在不同的时间切片上得到/失去执行权。

 

多线程技术的优点

1.线程相对于进程来说更加轻量,线程创建花费更少的资源和时间

2.线程间共享所属进程的公共内存

3.线程间上下文切换较进程有明显的优势

4.线程间的访问较进程更加简便

 

(线程的优点同时也是掌握它的难点,由于内存共享我们需要线程安全机制来确保多线程间的数据同步,关于这一部分我们后续再讨论)

 

关于线程创建API提供了两种实现方式

1.实现java.lang.Runnable接口

2.继承父类java.lang.Thread

 

实现Runnable接口

 我们可以通过封装runnable类来创建线程。而runnable类是通过实现java.lang.Runnable接口以及它的run方法获得的。当线程被调用时,run方法被执行。下面是实现Runnable接口的例子。

 

public class HeavyWorkRunnable implements Runnable {
 
    @Override
    public void run() {
        System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
            //Get database connection, delete unused data from DB
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
    }
 
    private void doDBProcessing() throws InterruptedException {
        Thread.sleep(5000);
    }
 
}

 

继承Thread父类

我们可以继承java.lang.Thread父类并重写run方法来创建线程。当线程被调用时,run方法被执行。下面是继承Thread父类创建线程的例子。

 

public class MyThread extends Thread {
 
    public MyThread(String name) {
        super(name);
    }
 
    @Override
    public void run() {
        System.out.println("MyThread - START "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
            //Get database connection, delete unused data from DB
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("MyThread - END "+Thread.currentThread().getName());
    }
 
    private void doDBProcessing() throws InterruptedException {
        Thread.sleep(5000);
    }
     
}

 

测试类如下

public class ThreadRunExample {
 
    public static void main(String[] args){
        Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
        Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
        System.out.println("Starting Runnable threads");
        t1.start();
        t2.start();
        System.out.println("Runnable Threads has been started");
        Thread t3 = new MyThread("t3");
        Thread t4 = new MyThread("t4");
        System.out.println("Starting MyThreads");
        t3.start();
        t4.start();
        System.out.println("MyThreads has been started");
         
    }
}

 

输出结果为

Starting Runnable threads
Runnable Threads has been started
Doing heavy processing - START t1
Doing heavy processing - START t2
Starting MyThreads
MyThread - START Thread-0
MyThreads has been started
MyThread - START Thread-1
Doing heavy processing - END t2
MyThread - END Thread-1
MyThread - END Thread-0
Doing heavy processing - END t1

 

当线程进入可执行状态(调用start方法)后,线程的执行顺序就由操作系统决定,当被分配到CPU时间时线程进入执行状态。尽管我们可以设定线程的优先度,但是它不总是管用(线程调度并不归JVM管理)。所以当我们多次运行上面的测试类时,线程起止的顺序不是确定不变的。

 

Runnable VS Thread

 如果你仅仅想创建一个线程去执行某项简单的任务你可以选择继承Thread父类。如果你想让程序更具有扩展性,执行更加多功能的任务你应该选择实现Runnable接口。

 

上面的话怎么理解呢,我们都知道Java API中一个类仅能继承一个父类,但是却可以实现复数个接口。个人更推荐通过实现Runnable接口的方式来创建线程。

 

 学习笔记3中我们将探讨线程休眠的概念。

 

参考:http://www.journaldev.com/1079/java-thread-tutorial/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值