1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 简述java的线程_JAVA线程简述

简述java的线程_JAVA线程简述

时间:2019-01-09 00:27:04

相关推荐

简述java的线程_JAVA线程简述

一.先谈谈并行与并发:

并行:是指两个或多个事件在同一时刻发生。

并发:是指连个或多个事件在同一时间间隔内发生。

二.接下来我们进入正题,讨论一下线程和进程:

1)什么是线程和进程?

进程:是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。

线程:线程是操作系统能够进行运算调度的最小单位。

它被包含在进程之中,是进程中的实际运作单位。

一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

2)进程和线程的区别?

1.进程和线程的主要差别在于它们是不同的操作系统资源管理方式。

2.进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。

3.线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

4.线程上下文的切换比进程上下文切换要快很多。

(1)进程切换时,涉及到当前进程的 CPU 环境的保存和新被调度运行进程的 CPU 环境的设置。

(2)线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。

3)进程间如何通讯?线程间如何通讯?

答:进程间通讯依靠 IPC 资源,例如管道(pipes)、套接字(sockets)等;

线程间通讯依靠 JVM 提供的 API,例如 wait()、notify()、notifyAll() 等方法,线程间还可以通过共享的主内存来进行值的传递。

三.多线程:

1)多线程和单线程有什么区别?

单线程程序:程序执行过程中只有一个有效操作的序列,不同操作之间都有明确的执行先后顺序,容易出现代码阻塞

多线程程序:有多个线程,线程间独立运行,能有效地避免代码阻塞,并且提高程序的运行性能

2)为什么要使用多线程?

1.使用多线程可以减少程序的响应时间。 在单线程的情况下,如果某个程序很耗时或者陷入长时间等待(如等待网络响应),此时程序将不会相应鼠标和键盘等操作,使用多线程后,可以把这个耗时的线程分配到一个单独的线程去执行,从而是程序具备了更好的交互性。

2.多CPU或多核心计算机本身就具有执行多线程的能力。 如果使用单个线程,将无法重复利用计算机资源,造成资源的巨大浪费。因此在多CPU计算机上使用多线程能提高CPU的利用率。

3.使用多线程能简化程序的结构,使用程序便于理解和维护。 一个非常复杂的进程可以分成多个线程来执行。

3)多线程一定快吗?

答:不一定。因为多线程在处理任务的时候,会存在一定的上下文切换,增加了需要的时间,处理少量数据时,处理速度明显比单线程慢。

4)创建线程有哪几种方式?

答:有两种创建线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创建一个Thread对象;二是直接继承Thread类。

5)两种创建方式有什么区别呢?

继承方式:

(1)Java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了.

(2)从操作上分析,继承方式更简单,获取线程名字也简单.(操作上,更简单)

(3)从多线程共享同一个资源上分析,继承方式不能做到.

实现方式:

(1)Java中类可以多实现接口,此时该类还可以继承其他类,并且还可以实现其他接口(设计上,更优雅).

(2)从操作上分析,实现方式稍微复杂点,获取线程名字也比较复杂,得使用Thread.currentThread()来获取当前线程的引用.

(3)从多线程共享同一个资源上分析,实现方式可以做到(是否共享同一个资源).

6)run() 方法和 start() 方法有什么区别?

答:start() 方法会新建一个线程并让这个线程执行 run() 方法;而直接调用 run() 方法知识作为一个普通的方法调用而已,它只会在当前线程中,串行执行 run() 中的代码。

7)怎么理解线程优先级?

答:Java 中的线程可以有自己的优先级。优先极高的线程在竞争资源时会更有优势,更可能抢占资源,当然,这只是一个概率问题。如果运行不好,高优先级线程可能也会抢占失败。

由于线程的优先级调度和底层操作系统有密切的关系,在各个平台上表现不一,并且这种优先级产生的后果也可能不容易预测,无法精准控制,比如一个低优先级的线程可能一直抢占不到资源,从而始终无法运行,而产生饥饿(虽然优先级低,但是也不能饿死它啊)。因此,在要求严格的场合,还是需要自己在应用层解决线程调度的问题。

在 Java 中,使用 1 到 10 表示线程优先级,一般可以使用内置的三个静态标量表示:

public final static int MIN_PRIORITY = 1;

public final static int NORM_PRIORITY = 5;

public final static int MAX_PRIORITY = 10;

数字越大则优先级越高,但有效范围在 1 到 10 之间,默认的优先级为 5 。

8)线程的运行状态

新建(NEW)状态:表示新创建了一个线程对象,而此时线程并没有开始执行。

可运行(RUNNABLE)状态:线程对象创建后,其它线程(比如 main 线程)调用了该对象的 start() 方法,才表示线程开始执行。当线程执行时,处于 RUNNBALE 状态,表示线程所需的一切资源都已经准备好了。该状态的线程位于可运行线程池中,等待被线程调度选中,获取 cpu 的使用权。

阻塞(BLOCKED)状态:如果线程在执行过程终于到了 synchronized 同步块,就会进入 BLOCKED 阻塞状态,这时线程就会暂停执行,直到获得请求的锁。

等待(WAITING)状态:当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用Object.wait方法或Thread.join方法,或者是等待java.util.concurrent库中的Lock或Condition时,就会出现这种情况;

计时等待(TIMED_WAITING)状态:Object.wait、Thread.join、Lock.tryLock和Condition.await 等方法有超时参数,还有 Thread.sleep 方法、LockSupport.parkNanos 方法和 LockSupport.parkUntil 方法,这些方法会导致线程进入计时等待状态,如果超时或者出现通知,都会切换会可运行状态;

终止(TERMINATED/dead)状态:当线程执行完毕,则进入该状态,表示结束。

四.线程安全问题:

五.高并发编程常用操作方法:

1)sleep关键字(线程休眠):

sleep是 Thread 类的静态方法,当前线程将睡眠 n 毫秒,线程进入阻塞状态。当睡眠时间到了,会解除阻塞,进行可运行状态,等待 CPU 的到来。睡眠不释放锁(如果有的话);

public static voidmain(String[] args) {new Thread(()->{for(int i=0;i<10;i++){

System.out.println(Thread.currentThread().getName()+":"+i);try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

},"线程1").start();

}

2)interrupt关键字(线程中断操作)

public static voidmain(String[] args) {

Thread thread= new Thread(()->{

System.out.println("工作了24小时,准备睡觉");try{

Thread.sleep(10000);

System.out.println("睡足了");

}catch(InterruptedException e) {

System.out.println("被打扰了");

}

},"线程1");

thread.start();//开始睡

try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}if(!thread.isInterrupted()){//该线程中断了吗

System.out.println("被人打扰");

thread.interrupt();//中断执行

}

}

interrupt可以中断线程,isInterrupted判断线程是否中断

3)join关键字(强制执行):

ThreadTest t1=new ThreadTest("A");

ThreadTest t2=new ThreadTest("B");

t1.start();

t1.join();

t2.start();

使用t1.join()之后,B线程需要等A线程执行完毕之后才能执行。需要注意的是,t1.join()需要等t1.start()执行之后执行才有效果

3)yield关键字(礼让执行):

public static voidmain(String[] args) {

Thread thread= new Thread(()->{for(int i=0;i<100;i++){if(i%3==0){

Thread.yield();//执行礼让

System.out.println("礼让了");

}

System.out.println(Thread.currentThread().getName()+":"+i);

}

},"线程1");

thread.start();//开始睡

for(int x=0;x<100;x++){

System.out.println(Thread.currentThread().getName()+":"+x);

}

}

礼让执行的时候调用yield方法,只礼让一次当前资源。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。