深入浅出Java中的多线程编程

进程与线程

  • 进程
    正在进行中的程序

  • 线程
    就是进程中一个负责程序执行的控制单元(执行路径)

    一个进程中可以多执行路径,称为多线程

    一个进程中至少要有一个线程

  • 多线程存在的意义
    创建多线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行

    而运行的指定代码就是这个执行路径的任务

  • 线程的创建的两种方式
    一.

  1. 定义一个类继承Thread类
  2. 覆盖Thread类中的run方法
  3. 直接创建Thread的子类对象创建线程
  4. 调用start方法开启线程并调用线程的任务run方法执行
    二 .(常用)
  5. 定义类实现Runnable接口
  6. 覆盖接口中run方法,将线程的任务代码封装到run方法中
    3.通过Thread类创建线程对象,并将Runnable接口的子类对象作为构造函数的参数进行传递 (因为线程的任务都封装在Runnable接口的子类对象的run方法中,所以要在线程对象创建时,就明确其任务)
  7. 调用线程对象的start方法开启线程
  • 实现Runnable接口的好处
  1. 将线程的任务从线程的子类中分离出来,进行了单独的封装
    按照面向对象的思想将任务封装成对象
  2. 避免了java单继承的局限性
  • 多线程的特性
    好处:解决了多部分同时运行的问题
    弊端:线程多导致效率低

其实应用程序的执行都是cpu在做着快速的切换完成的,这个切换是随机的

JVM启动时,就启动了多个线程 ,至少是有两个线程是可以分析出来了的
1. 主线程 2。垃圾回收线程

多线程的运行(栈情况)

多线程运行图

多线程分配多个栈空间,若这个线程结束,这个线程的内存空间被释放

多线程的状态图

多线程的状态

多线程安全问题

用Runnable接口把任务封装成一个对象,用多个线程处理一个任务时,可能引起安全隐患。

产生的原因:

  • 多个线程在操作共享的数据
  • 操作共享数据的代码有多条
    当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致安全问题的产生

多线程安全问题的解决

解决思想:就是将多条操作共享数据的代码块封装起来,当有线程执行代码的时候,其他线程不可以参与运算
在java中,同步代码块就可以解决这种问题

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

原理:
在这个代码块前面加一个锁,这个线程运行期间,别的线程进不来。在这里这个对象就是一个

锁是一个对象,不同的对象代表不同的锁

同步的好处: 解决的线程的安全问题

同步的弊端:相对效率有点低,因为同步外的线程都会判断同步锁

同步的前提

同步中 必须有多个线程并使用同一个锁

同步函数

函数与同步代码块都是一个封装,但是他俩的区别是,一个普通的封装,另外一个是有特性的封装。 我们可以把函数也变成一个有特性的封装。
即把synchronized关键字放到函数上即可
public synchronized void eat()
同步代码块与同步函数都能解决线程的安全问题

同步函数的锁是谁?

同步函数用的锁:函数都是被对象调用的,而同步函数的锁就this。

静态同步函数的锁是谁?

静态同步函数使用的锁是,该函数锁所属的字节码文件对象
**可以用getClass方法获取,也可以用当前类名.class获取

死锁

常见的情景之一:同步嵌套

class Test implements Runnable
{
    private boolean flag;
    Test(boolean flag)
    {
        this.flag = flag;
    }

    public void run()
    {
        
        if(flag)
        {
            while(true)
                synchronized(MyLock.locka)
                {
                    System.out.println(Thread.currentThread().getName()+"..if   locka....");
                    synchronized(MyLock.lockb)              {
                        
                        System.out.println(Thread.currentThread().getName()+"..if   lockb....");
                    }
                }
        }
        else
        {
            while(true)         
                synchronized(MyLock.lockb)
                {
                    System.out.println(Thread.currentThread().getName()+"..else  lockb....");
                    synchronized(MyLock.locka)
                    {
                        System.out.println(Thread.currentThread().getName()+"..else   locka....");
                    }
                }
        }

    }

}

class MyLock
{
    public static final Object locka = new Object();
    public static final Object lockb = new Object();
}




class DeadLockTest 
{
    public static void main(String[] args) 
    {
        Test a = new Test(true);
        Test b = new Test(false);

        Thread t1 = new Thread(a);
        Thread t2 = new Thread(b);
        t1.start();
        t2.start();
    }
}

你可能感兴趣的:(深入浅出Java中的多线程编程)