java实现多线程(上)

一、三个基本概念:程序、进程、线程

  程序:是为了完成特定的任务、用某种语言所编写的一组语言的集合。即指一段静态的代码。

  进程:是程序的一次执行过程,或是正在运行的程序。是一个动态的过程:有它自身的产生、存在和消亡过程。

    >进程作为资源分配的单位,系统在巡行时会为每个进程分配不同的内存区域。

  线程:进程可以进一步细化为线程,是一个程序内部的一条执行路径。

    >若一个进程同一时间并行的执行多个线程,就是支持多线程。

    >线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc)。线程的切换开销小。

    >一个进程的多个线程可以共享资源,这使得线程间的通讯更加便捷高效,但是同样的带来了安全隐患。

 

二、单核CPU和多核CPU的理解:

单核CPU:其实是一种假的多线程,因为在一个时间单元内,只能执行一个线程的任务。但是由于CPU时间单元特别短,感觉就好像是同时在做一样。

多核CPU:多核才是正在的多线程,能更好的发挥多线程的效率,一个java应用程序java.exe其实至少有三个线程:main()主线程、gc()垃圾回收线程、异常处理线程。异常发生,会影响主线程。

 

三、并发和并行:

并行:多个CPU同时执行多个任务。多个人做不同事。

并发:一个CPU同时执行多个任务。比如:秒杀、多个人做一件事。

 

四、多线程的创建:

方式一:继承于Thread类

1.创建一个继承于Thread类的子类

2.重写Thread类的run()——>将此线程执行的操作放到run()中

3.创建Thread类的子类的对象

4.通过此对象调用start()

例如:遍历100以内的所有偶数:

class example extends Thread{
@override
public void run(){
forint i = 0;i<100;i++){
  if(i %2 == 0){
System.out.print(i);
}}}}
public class exampletest{
public static void main(String【】args){

example ex = new example();//每创建一个对象,就可以创建一个线程的调用

ex.start();//启动当前线程,调用当前线程的run()方法
System.out.print("hello");
}
}

这个时候main线程下的打印“hello”和start方法的遍历就是分开进行的。

方式二:实现Runnable接口

1.创建一个实现了Runnable接口的类

2.实现类去实现Runnable中的抽象方法:run()

3.创建实现类的对象

4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象

5.通过Thread类的对象调用start()

class example implements Runnable{
@override
public void run(){
forint i = 0;i<100;i++){
  if(i %2 == 0){
System.out.print(i);
}}}}
public class exampletest1{
public static void main(String【】args){

example ex = new example();//创建实现类的对象
Thread th = new Thread(ex);//将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象

th.start();//启动当前线程,调用当前线程的run()方法(通过查看源码,其实这个run()调用的是Runnable类型的target,而这个就是作为实参传递的实现类对象!)
System.out.print("hello");
}

比较以上两种创建线程的方式:

开发中:优先选择实现Runnable接口的方式

原因:1.实现的方式没有类的单继承性的局限性

   2.实现的方式更适合来处理多个线程有共享数据的情况。

联系:public class Thread implements Runnable(其实都是Runnable中的run())

相同点:两种方式都要重写run(),将线程要执行的逻辑声明在run()中。

 

五、Thread类的有关方法:

void start:启动线程,并执行对象的run()方法

run():线程在被调用时执行的操作

String getName():返回线程的名称

void steName(String name):设置该线程名称

static Thread currentThread():返回当前线程。在Thread子类中就是this,通常用于主线程和Runnable实现类。

static void yield():线程让步

  >暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程(注意:暂停执行的线程,在抢占的时候仍然有机会抢到资源执行)

  >若队列中没有同优先级的线程,忽略此方法。

join():当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到join()方法加入的join线程执行完为止。

  >低优先级的线程也可以获得执行

static void sleep(long millis):(时间单位:毫秒)

  >令当前活动线程在指定时间段内放弃对CPU的控制,使其他线程有机会被执行,时间到后重新排队。

  >抛出InterruptedException异常。

stop():强制线程生命期结束,不推荐使用(过时了)

boolean isAlive():判断线程是否还活着。

 

六、线程的调度:

java的调度方法:

  >同优先级线程组成先进先出(先到先服务),使用时间片策略

  >对高优先级,使用优先调度的抢占式策略

线程的优先级等级:

  >MAX_PRIORITY: 10

  >MIN_PRIORITY: 1

  >NORM_PRIORITY: 5

涉及的方法:

  >getPriority():返回线程优先值

  >setPriority(int newPriority):改变线程的优先级

说明:

  >线程创建时继承父线程的优先级

  >低优先级只是获得调用的概率低,并非一定是在高优先级线程之后才被调用

 

posted @ 2019-05-09 13:55  黑暗之魂DarkSouls  阅读(162)  评论(0编辑  收藏  举报