JAVA中的多线程与线程安全

(一)线程与进程

  • 进程:正在运行的一个程序(qq ide 浏览器)
    系统会为这个进程分配独立的内存资源
  • 线程:具体执行任务的最小单位
  • 线程与进程的关系:一个进程至少拥有一个线程(主线程 运行起来就执行的线程)
  • 线程的特点:
    1.线程之间共享内存资源(进程申请的)
    2.线程之间可以通信(数据传递)
    3.每一个进程都有自己的生命周期
    4.线程的生命周期:也就是这个线程的状态
  • 线程的状态:
    NEW:新建状态
    RUNNABLE:就绪状态 只要抢到时间片就可以运行
    BLOCKED:阻塞状态 sleep wait都可能阻塞一个线程
    WAITING:等待状态
    TIME_WAITING
    TERMINATED: 终止状态

    如图所示:
    展示图1.png

(二)多线程

  • 子线程:在主线程进行的同时为了不妨碍主线程的工作而创建
  • 为什么要创建子线程
    如果在主线程中存在有比较耗时的操作:下载视频 上传文件 数据处理,这些都会阻塞主线程,后面的任务必须等待这些任务执行完毕之后才能执行,用户体验比较差
  • 如何创建一个子线程

    如图示方法:
    展示图.png
  • 方式一:写一个类继承于Thread 实现run方法
    步骤一:定义一个类继承Thread并且实现run方法
class TestThread extends Thread{
    //实现run方法
    //方法里面就是具体需要执行的代码
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        for (int i = 0; i <=100; i++) {
              System.out.println(name + " "+i);
              if(this!=MyClass.testThread1) {
                  if (i == 10) {
                      try {
                          MyClass.testThread1.join();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }
        }
        super.run();
    }
}

步骤二:创建对象 调用Thread方法实现功能

          String name = Thread.currentThread().getName();
          System.out.println(name);
          //创建Thread的对象
          TestThread testThread = new TestThread();
           //设置子线程的名称
           testThread.setName("子线程1");
           //开启方法
           testThread.start();
  • 实际效果:
    首先获取了线程的名字
    改变了子线程的名字
    实现了线程的功能


    效果图.png
  • Thread里面的具体方法:
  • join:让当前这个线程阻塞 等join的线程执行完毕在执行
    1.setName:设置线程名称
    2.getName:获取线程名称
    3.currThread:获取当前运行的线程对象
    4.start:开启任务
  • 方式二:实现runable接口 实现run方法
    步骤一:创建任务 创建类实现Runnable接口
class PXDthread implements Runnable{
    public void run() {
        for (int i = 0; i <=100; i++) {
            System.out.println(Thread.currentThread().getName());
                }
    }
}

步骤二:使用Thread为这个任务分配线程
方式一:直接创建对象调用方法

 PXDthread pt = new PXDthread();
        //使用Tread操作 这个任务
       Thread t = new Thread(pt);
       t.setName("子线程2");
       t.start();

方式二:使用匿名类

Thread t =new Thread(new Runnable() {
             @Override
             public void run() {
                 for (int i = 0; i <=100; i++) {
                     System.out.println(Thread.currentThread().getName());
                 }
             }
         });
         t.setName("子线程1");
         t.start();

方式三:创建线程的同时直接开启线程任务不需要操作线程对象本身

new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <=100; i++) {
                    System.out.println(Thread.currentThread().getName());
                }
            }
        }).start();

方式四:使用lambda表达式 不建议:阅读性太差

        new Thread(()->{ for (int i = 0; i <=100; i++) {
            System.out.println(Thread.currentThread().getName());
        }
        }).start();

(三)线程安全

  • 方法:synchronized Lock 加锁解锁
  • synchronized

方式一:同步代码块
模板:synchronized(监听器/对象/锁){
//需要同步的代码
}
实际运用:

synchronized (obj){
                //需要同步的代码
            }
            if(NUM>0) {
                System.out.println(name + "出票" + NUM);
                  NUM--
            }else{
                break;
            }
  • 作用:可以保证在进行代码块的时候不会被其他线程所打断
    方式二:同步方法
    模板:public synchronized void test()<=>synchronized(this){test();}
    注意事项:必须确保对个对象调用的同步方法时操作的是同一个对象,若不是同一对象还是使用同步代码块方法

(四)今日小结:

每一天依旧是一样的辛劳,但是还算是有收获的,每天看似很小的进步,慢慢积累就会有很大提高了,不知不觉已经过了这么多天了。既然选择了这条道路也就只能一步步坚持走下去了。

你可能感兴趣的:(JAVA中的多线程与线程安全)