JavaSE----多线程总结

JavaSE多线程总结

1.进程与线程的定义

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

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

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

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

2.实现线程的方法

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

     @Override
     public void run(){}

  }
	  //创建线程对象
	  Thread t = new MyThread(new Runnable);
	  //启动线程
	  t.start();
  1. 采用匿名内部类:
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();
            }
        }
    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值