多线程

进程:
         正在运行的程序,是系统进行资源分配和调用的独立单位。
         每一个进程都有它自己的内存空间和系统资源。
     线程:
         是进程中的单个顺序控制流,是一条执行路径
         一个进程如果只有一条执行路径,则称为单线程程序。
         一个进程如果有多条执行路径,则称为多线程程序。
 
   举例:
       扫雷程序,迅雷下载
  
   注意两个词汇的区别:并行和并发。
         前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。
         后者是物理上同时发生,指在某一个时间点同时运行多个程序。
 
  Java程序的运行原理:
          由java命令启动JVM,JVM启动就相当于启动了一个进程。
          接着有该进程创建了一个主线程去调用main方法。
 
  思考题:
          jvm虚拟机的启动是单线程的还是多线程的?
              多线程的。
              原因是垃圾回收线程也要先启动,否则很容易会出现内存溢出。
              现在的垃圾回收线程加上前面的主线程,最低启动了两个线程,所以,jvm的启动其实是多线程的。

通过查看API,我们知道了有2中方式实现多线程程序。
 
  方式1:继承Thread类。
  步骤
          A:自定义类MyThread继承Thread类。
          B:MyThread类里面重写run()
          C:创建对象
          D:启动线程

public class SellTicketDemo {
    public static void main(String[] args) {
        // 创建三个线程对象
        SellTicket st1 = new SellTicket();
        SellTicket st2 = new SellTicket();
        SellTicket st3 = new SellTicket();

        // 给线程对象起名字
        st1.setName("窗口1");
        st2.setName("窗口2");
        st3.setName("窗口3");

        // 启动线程
        st1.start();
        st2.start();
        st3.start();
    }
}

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

public class SellTicketDemo {
    public static void main(String[] args) {
        // 创建资源对象
        SellTicket st = new SellTicket();

        // 创建三个线程对象
        Thread t1 = new Thread(st, "窗口1");
        Thread t2 = new Thread(st, "窗口2");
        Thread t3 = new Thread(st, "窗口3");

        // 启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

run()和start()的区别?
        run():仅仅是封装被线程执行的代码,直接调用是普通方法
        start():首先启动了线程,然后再由jvm去调用该线程的run()方法。

注意:
          线程默认优先级是5。
          线程优先级的范围是:1-10。
          线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才     能看到比较好的效果。

同步解决线程安全问题
        A:同步代码块
            synchronized(对象) {
                需要被同步的代码;
            }
            这里的锁对象可以是任意对象。           
        B:同步方法
            把同步加在方法上。
            这里的锁对象是this      
        C:静态同步方法
            把同步加在方法上。          
            这里的锁对象是当前类的字节码文件对象(反射再讲字节码文件对象)
   

虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,
  为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock。
 
  Lock:
          void lock(): 获取锁。
          void unlock():释放锁。  
  ReentrantLock是Lock的实现类.
 

sleep和wait有什么区别?
对时间的指定。
     1,sleep方法必须指定时间。
     2,wait方法有重载形式,可以指定时间,也可以不指定时间。
对于执行权和锁的操作.
     1,sleep():释放执行权,不释放锁,因为肯定能醒,肯定可以恢复到临时阻塞状态。
     2,wait():释放执行权,释放锁,因为wait不释放锁,如果没有指定时间,那么其他线程都进行不了同步,无法将其唤醒。

原文地址:https://www.cnblogs.com/lsymove/p/11257980.html