java多线程1:进程和线程的概念

进程和线程

说到多线程,不妨先谈一谈进程的概念。在百度百科中对进程的解释如下:

 

 

 其实简单理解程序的实体,就是我们操作系统运行的一个基本单元

 

 

 比如我们系统运行着的微信这个聊天软件,就可以理解为一个进程。

 

那么线程又是什么呢?

线程可以理解为进程中独立运行的子任务就是一个线程,比如好友视频线程、下载文件线程、传输数据线程、微信聊天线程等。

那多线程的好处又是什么呢?

1、发挥多核CPU的能力

现在,多处理器系统正日益盛行,并且价格不断降低,即时在低端服务器和中断桌面系统中,通常也会采用多个处理器,这种趋势还在进一步加快,因为通过提高时钟频率来提升性能已变得越来越困难,处理器生产厂商都开始转而在单个芯片上放置多个处理器核。试想,如果只有单个线程,双核处理器系统上程序只能使用一半的CPU资源,拥有100个处理器的系统上将有99%的资源无法使用。多线程程序则可以同时在多个处理器上执行,如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率。

2、提高单处理器的吞吐率

如果程序是单线程的,那么当程序等待某个同步I/O操作完成时,处理器将处于空闲状态。而在多线程程序中,

如果一个线程在等待I/O操作完成,另一个线程可以继续运行,使得程序能在I/O阻塞期间继续运行。

 

注意:多线程是异步的,所以千万不要把代码的顺序当成线程执行的顺序,线程被调用的时机是随机的。

 

java中使用多线程

1:继承Thread

public class Mythread extends Thread {

    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "在运行!");

        }
    }
}
@Test
	public void test1() {
		// 继承Thread,重写父类的run()方法。
		Mythread mt0 = new Mythread();
	    mt0.start();

	    for (int i = 0; i < 5; i++) {
	    		// Thread.currentThread():返回代码段正在被哪个线程调用的信息
	        System.out.println(Thread.currentThread().getName() + "在运行!");
	    }
	}

  运行结果:

Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!

  

2:实现Runnable接口

public class Mythread2 implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "在运行!");
        }
    }

} 
@Test
	public void test2() {
		// 实现Runnable接口。和继承自Thread类差不多,不过实现Runnable后,还是要通过一个Thread来启动:
		Mythread2 mt0 = new Mythread2();
		new Thread(mt0).start();

		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName() + "在运行!");
		}
	}

  运行结果:

Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
Thread-0在运行!
main在运行!
main在运行!
main在运行!
main在运行!
main在运行!

  

其实Thread类也是实现的Runnable接口。两种实现方式对比的关键就在于extends和implements的对比,当然是后者好。

因为继承只能单继承,实现可以多实现,而且实现的方式对比继承的方式,也有利于减小程序之间的耦合。

因此,多线程的实现几乎都是使用的Runnable接口的方式。不过,后面的文章,为了简单,就用继承Thread类的方式了。

 

线程状态

虚拟机中的线程状态有六种,定义在Thread.State中:

1、新建状态NEW

new了但是没有启动的线程的状态。比如"Thread t = new Thread()",t就是一个处于NEW状态的线程

2、可运行状态RUNNABLE

new出来线程,调用start()方法即处于RUNNABLE状态了。处于RUNNABLE状态的线程可能正在Java虚拟机中运行,也可能正在等待处理器的资源,因为一个线程必须获得CPU的资源后,才可以运行其run()方法中的内容,否则排队等待

3、阻塞BLOCKED

如果某一线程正在等待监视器锁,以便进入一个同步的块/方法,那么这个线程的状态就是阻塞BLOCKED

4、等待WAITING

某一线程因为调用不带超时的Object的wait()方法、不带超时的Thread的join()方法、LockSupport的park()方法,就会处于等待WAITING状态

5、超时等待TIMED_WAITING

某一线程因为调用带有指定正等待时间的Object的wait()方法、Thread的join()方法、Thread的sleep()方法、LockSupport的parkNanos()方法、LockSupport的parkUntil()方法,就会处于超时等待TIMED_WAITING状态

6、终止状态TERMINATED

线程调用终止或者run()方法执行结束后,线程即处于终止状态。处于终止状态的线程不具备继续运行的能力

 

参考文献

1:《Java并发编程的艺术》

2:《Java多线程编程核心技术》

posted @ 2021-12-13 16:23  让我发会呆  阅读(102)  评论(0编辑  收藏  举报