JavaSE----多线程总结

    技术2025-06-27  10

    JavaSE多线程总结

    1.进程与线程的定义

    进程:一个应用程序。 线程:一个应用程序的执行场景或是执行单元

    举例: 进程1:阿里巴巴 线程A: 马老师 线程B: 前台小姐姐

    进程2:京东 线程A: 刘老师 线程B: 前台小姐姐

    进程1和进程2是独立不共享的 线程1和线程2堆内存和方法区共享;栈空间独立不共享

    2.实现线程的方法

    编写一个类,直接继承Thread,重写run方法: //定义线程类 class MyThread extends Thread{ @Override public void run(){} } //创建线程对象 MyThread m = new MyThread; //启动线程 m.start(); `编写一个类,实现Runnable接口,重写run方法: //定义一个可运行的类 class MyThread implements Runnable{ @Override public void run(){} } //创建线程对象 Thread t = new MyThread(new Runnable); //启动线程 t.start(); 采用匿名内部类: Thread t = new Thread(new Runnable(){ @Override public void run(){} }); //启动线程 t.start();

    3.线程的生命周期

    注意:锁池不算生命周期中的状态。线程生命周期五大状态:开始,就绪状态,运行状态,阻塞状态,结束。

    4.获取线程的名字

    currentThread()方法:

    public static void main(String args[]){ Thread currentThread = Thread.currentThread(); //获取当前线程的名字 System.out.println(currentThread.getName()); //创建线程类对象 MyThread2 m2 = new MyThread2(); //修改线程对象的名字 m2.setName("T1"); //获取线程对象的名字 默认名字为Thread-0 String s = m2.getName(); System.out.println(s); } class MyThread2 extends Thread{ @Override public void run(){ for(int i=0; i<100; i++){ //currentThread就是当前线程对象 Thread currentThread = Thread.currentThread(); System.out.println(currentThread.getName()+" "+i); } } }

    5.线程安全

    未来的开发中,我们的项目是运行在服务器上的,服务器已经将线程定义并穿创建了,我们需要做的就是确保我们的代码 数据是否是安全的?

    5.1 线程安全问题出现的条件:

    ①多线程并发 ②有共享资源 ③共享资源有修改的行为

    5.2如何解决线程安全问题:

    存在线程安全问题时:需要执行线程排队处理(多个线程不能并发),也称之为 “线程同步机制”。

    5.3同步/异步机制:

    异步编程模型:线程A和线程B,各自执行各自的,A不管B,B不管A,谁也不需要谁(多个线程并发,效率高,安全低) 同步编程模型:线程A和线程B,当线程A执行时,线程B必须排队等候线程A执行完毕后再进行操作;(多个线程排队执行,效率低,安全高)

    5.4synchronized三种写法:

    ①同步代码块 synchronized (线程共享对象){ 同步代码块; } ②在实例方法上使用synchronized 表示共享对象一定this 并且同步代码块是整个方法体 ③在静态方法上使用synchronized 表示找类锁 类锁永远只有一把 就算创建了100个对象,类锁也只有一把

    5.5实际开发中如何解决线程安全问题:

    synchronized会让程序的执行效率降低,用户体验极差 ①尽量使用局部变量代替 “实例变量和静态变量” ②如果必须是实例变量,那么可以考虑创建多个对象,这样实例变量的内存就不共享了(1个线程对应1个对象,100个线程对应100个对象, 对象不共享,就没有数据安全问题了) ③如果不能使用局部变量,对象也不能创建多个,这个时候就只能选择synchronized,线程同步机制

    5.6线程其他内容:

    ①守护线程 .setDaemon()

    java中线程分为两大类: 一种是用户线程:main属于用户线程 一种是守护线程(后台线程):垃圾回收机制 守护线程的特点: 一般守护线程是死循环,所有的用户线程只要结束,守护线程就会自动结束

    ②定时器

    ③ 实现线程的第三种方式 Future方式,实现Callable接口(JDK8新特性) 这种方式可以获得返回值

    ④关于Object的wait和notify方法(生产者消费者模式) wait方法和notify方法不是线程对象的方法,是java中任何一个java对象都有的方法 wait方法作用: Object o = new Object; o.wait(); 让正在o对象上活动的线程进入等待状态,无期限等待,知道被唤醒,o.wait()会让 “当前线程”进入等待状态 o.notify()唤醒正在o对象等待的线程 o.notifyALL()唤醒正在o对象等待的所有线程

    5.7生产者/消费者模式

    public class TestThread10 { public static void main(String[] args) { // List list = new ArrayList(); Thread t1 = new Thread(new Producer(list)); Thread t2 = new Thread(new Consumer(list)); t1.setName("生产者线程"); t2.setName("消费者线程"); t1.start(); t2.start(); } } //生产线程 class Producer implements Runnable{ //仓库 private List list; public Producer(List list){ this.list = list; } @Override public void run() { //一直生产(死循环模拟一直生产) while (true){ synchronized (list) { if (list.size() > 0) { //当前线程进入等待状态,并释放list集合的锁 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //程序执行到这里说明仓库是空的,需要生产 Object obj = new Object(); list.add(obj); System.out.println(Thread.currentThread().getName()+"-->"+obj); list.notify(); } } } } //消费线程 class Consumer implements Runnable{ private List list; public Consumer(List list){ this.list = list; } @Override public void run() { //一直消费(死循环模拟一直消费) while (true){ synchronized (list) { if (list.size() == 0) { //仓库空了,消费者等待,并且释放list的锁 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //程序执行到这里说明仓库满了,需要消费 Object obj = list.remove(0); System.out.println(Thread.currentThread().getName()+"-->"+obj); list.notify(); } } } }

    多线程这一块总结了这么多,把学到的知识梳理了一下,可能还有些没有总结到,希望这些对大家有帮助。另外生产者消费者这一块,我也是看了好久,也希望各位大佬能给出自己的理解供参考~!

    Processed: 0.011, SQL: 9