多线程(一)

初识多线程(理解)
(1)多线程:一个应用程序有多条执行路径
进程:

  • 1.正在执行的应用程序,是系统进行资源分配和调用的独立单位。
  • 2.每一个进程都有它自己的内存空间和系统资源。

线程:

  • 1.是进程中的单个顺序控制流,是一条执行路径。
  • 2.一个进程如果只有一条执行路径,则称为单线程程序。
  • 3.一个进程如果有多条执行路径,则称为多线程程序。

单线程:一个应用程序只有一条执行路径。
多线程:一个应用程序有多条执行路径。 

并行和并发:
  前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。
  后者是物理上同时发生,指在某一个时间点同时运行多个程序。

Java程序的运行原理:
  由java命令启动JVM,JVM启动就相当于启动了一个进程。
接着有该进程创建了一个主线程去调用main方法。

  多进程的意义?
    答:提高CPU的使用率。
  多线程的意义?
    答:提高应用程序的使用率。程序的执行其实都是在抢CPU的资源,CPU的执行权。

多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高的几率抢

到CPU的执行权。我们是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。

(2)Java程序的运行原理及JVM的启动是多线程的吗?

答:是多线程的。
  原因是垃圾回收线程也要先启动,否则很容易会出现内存溢出。
  现在的垃圾回收线程加上前面的主线程,最低启动了两个线程,所以,jvm的启动其实是多线程的。

(3)多线程的实现方案(自己补齐步骤及代码 掌握)
A:继承Thread类

步骤:
 1:自定义类MyThread继承Thread类;
 2:MyThread类里面重写run();
 3:创建对象;
 4:启动线程.

public class MyThread extends Thread {
    @Override
    public void run() {
        // 自己写代码
        // System.out.println("好好学习,天天向上");
        // 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进
        for (int x = 0; x < 200; x++) {
            System.out.println(x);
        }
    }
}

该类要重写run()方法,为什么呢?
   不是类中的所有代码都需要被线程执行的。
而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。


B:实现Runnable接口

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
        // 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
            System.out.println(Thread.currentThread().getName() + ":" + x);
        }
    }
}

步骤:
 1:自定义类MyRunnable实现Runnable接口;
 2:重写run()方法;
 3:创建MyRunnable类的对象;
 4:创建Thread类的对象,并把C步骤的对象作为构造参数传递.

(4)线程的调度和优先级问题
1:线程的调度
  a:分时调度.
  b:抢占式调度 (Java采用的是该调度方式).
2:获取和设置线程优先级
  a:默认值是5.
  b:范围是MIN_PRIORITY(1)~MAX_PRIORITY(10).

(5)线程的控制(常见方法)

  • A:休眠线程 public static void sleep(long millis)
  • B:加入线程 public final void join()
  • C:礼让线程 public static void yield()
  • D:守护线程 public final void setDaemon(boolean on)
  • E:终止线程(掌握) public void interrupt()

(6)线程的生命周期

描述线程的生命周期?
新建:创建线程对象。
就绪:有执行资格,没有执行权。
运行:有执行资格,有执行权。
阻塞:由于一些操作让线程处于了该状态。没有执行资格,没有执行权。

   而另一些操作却可以把它重新激活,激活后处于就绪状态。
死亡:线程对象变成垃圾,等待被回收。

(7)同步的特点:

前提:
   多个线程
解决问题的时候要注意:
    多个线程使用的是同一个锁对象
同步的好处:
  同步的出现解决了多线程的安全问题。
同步的弊端:
  当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。


(9)多线程安全问题的原因(也是我们以后判断一个程序是否有线程安全问题的依据)
1:是否有多线程环境
2:是否有共享数据
3:是否有多条语句操作共享数据
(10)同步解决线程安全问题
A:同步代码块

同步代码块的锁对象是谁呢?
 任意对象。

synchronized(对象) {
        需要被同步的代码;
}

//这里的锁对象可以是任意对象。    


B:同步方法
把同步关键字加在方法上。
这里的锁对象是this
C:静态方法

静态方法及锁对象问题?

 静态方法的锁对象是谁呢?
 类的字节码文件对象。(反射会讲)

(11)回顾以前的线程安全的类
A:StringBuffer
B:Vector
C:Hashtable
D:如何把一个线程不安全的集合类变成一个线程安全的集合类
用Collections工具类的方法即可。

List<String> list1 = new ArrayList<String>();// 线程不安全
        List<String> list2 = Collections
                .synchronizedList(new ArrayList<String>()); // 线程安全
原文地址:https://www.cnblogs.com/crazypokerk/p/9107746.html