对于学习JAVA多线程的总结

@对于学习JAVA多线程的总结

对于多线程

因为本人为计算机专业的学生,所以此处不对线程,进程的概念、优先级、动态过程等进行过多的描述总结,主要对线程的创建,同步方法的使用等进行总结。

关于线程

一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。

线程的创建

  1. 自定义线程类继承Thread类
    然后重写run()方法,编写线程执行体,
    启动线程:子类对象.start()
public class Testthread1 extends Thread{
  @Override
  public void run() {
      for(int i= 0;i < 10; i++){
          System.out.println("总结多线程-"+i);
      }
  }

  public static void main(String[] args) {
      //主线程

      //创建线程对象并调用start()方法开启线程
      Testthread1 testthread1 = new Testthread1();
      testthread1.start();
  }
}
 注:线程开始不一定立即执行,由CPU进行调度
  1. 实现Runnable接口
    定义MyRunnable类实现Runnable接口
    实现run()方法,编写线程执行体,
    启动线程:传入目标对象+Thread对象.start()
public class Testthread2 implements Runnable{
  @Override
  public void run() {
      for(int i= 0;i < 10; i++){
          System.out.println("总结多线程-"+i);
      }
  }

  public static void main(String[] args) {
      //主线程

      //创建Runnable接口的实现类对象并调用start()方法开启线程
      Testthread2 testthread2 = new Testthread2();

      new Thread(testthread2).start();
  }
}

对比上一种方法,不建议使用继承Thread类:避免OOP单继承局限性,实现Runnable接口更灵活方便,方便同一个对象被多个线程调用。

  1. 实现Callable接口
    创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
    创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
    使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
    调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
import java.util.concurrent.*;

public class Testthread3 implements Callable<Integer> {
  @Override
  public Integer call() throws Exception {
      System.out.println("实现Callable接口");
      return 10;
  }

  public static void main(String[] args) throws ExecutionException, InterruptedException {

      FutureTask<Integer>futureTask = new FutureTask<Integer>(new Testthread3());
      new Thread(futureTask).start();
      try {
          Integer integer = futureTask.get();
          System.out.println(integer);
      } catch (InterruptedException e) {
          e.printStackTrace();
      } catch (ExecutionException e) {
          e.printStackTrace();
      }
  }
}

关于线程的操作

  1. 线程停止
    可以使用JDK提供的stop()方法,但不推荐使用,更推荐线程自己停下。可以使用一个标志位进行终止变量。

  2. 线程休眠
    使用sleep方法,常用来模拟网络延时等,sleep存在异常InterruptedException,且sleep不会释放锁。

  3. 线程礼让
    使用yleld方法,让当前正在执行线程暂停,但不阻塞只是由运行状态转变为就绪状态。注:礼让不一定会成功。

  4. 线程强制执行
    使用Join方法,合并线程,待此线程执行完毕后再执行其他线程,其他线程阻塞。

线程同步机制

线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等前一个线程使用完毕后下一个才使用。
注:一个线程持有锁会导致其他需要此锁的线程挂起;线程过多和优先级倒置会引起性能问题。

同步方法和同步块

线程同步是具有不安全性的,我们需要使用synchronized关键字解决。
用法一:synchronized方法,在定义方法时加入synchronized关键字。
注:synchronized方法控制对对象的访问,该方法调用对象的锁后会独占该锁,直到该方法释放锁后面的线程才能获得锁,所以当使用在一个大方法时会影响效率。
用法二:同步块,synchronized(Obj){},Obj为同步监视器,也可以是任何对象,该对象就是进行增删改查的对象,把对象锁好即可。

死锁概念和避免死锁

多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或多个线程都在等待对方释放资源都停止执行的情形。某一个同步块同时拥有两个以上对象的锁时就可能发生死锁问题。
产生死锁的必要条件:

  1. 互斥条件:一个资源每次只能被一个进程使用。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
    以上条件破解一个或多个就可避免死锁发生
  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值