Java=多线程-高并发和线程安全,volatile,原子类

本文介绍了Java中的多线程概念,包括并行与并发的区别,线程的状态以及创建线程的方式。接着讨论了高并发和线程安全问题,强调了可见性、有序性和原子性。volatile关键字被详细解释,用于解决可见性和有序性,但无法保证原子性。最后,原子类如AtomicInteger等被介绍,它们提供了原子操作,确保了在多线程环境中的数据安全性。
摘要由CSDN通过智能技术生成

一,多线程

并行与并发

并行: 两个事件,在同一个时刻,都在发生
并发: 两个事件,在同一个时间段内,都在发生(交替执行)

进程与线程

进程: 正在内存中运行的程序,我们称为进程
线程: 进程中完成某个小功能的模块(进程中用执行某个功能的执行单元)

线程是属于某个进程的
      每个进程都有独立的内存空间(独立的栈独立的堆等),并且至少有一个线程
      每个线程都会跟进程申请一块独立栈,共享进程的堆 

线程调用是指CPU在不同的进程不同的线程之间进行快速切换
    
线程调度的分类:
    分时调度: 每个线程平均拥有CPU的执行权
    抢占式调用: 每个线程随机分配CPU的执行权(具体的分配多少和线程优先级有关)
    我们Java程序(Java进程)中所有线程采用抢占式调度 

线程的状态

Thread对象共有6种状态:NEW(新建),RUNNABLE(运行),BLOCKED(阻塞),WAITING(等待),TIMED_WAITING(有时间的等待),TERMINATED(终止);状态转换如下:

 

1.Thread类

a.Thread类是什么?
    Thread是Java定义好的,代表线程的类,只要创建该类的一个对象,其实就是创建了一个线程
   
b.Thread类的构造方法
    public Thread(); // 无参构造,线程会有默认的名字,Thread-0,Thread-1等...
	public Thread(String name); //带有线程名字的构造

	public Thread(Runnable r);//带有线程任务的构造
	public Thread(Runnable r,String name); //即带有线程名字,又带有线程任务的构造
    
c.Thread类的成员方法
    public String getName(); //获取线程的名字
	public void setName(String name);//修改线程的名字

	public void run();//代表线程要执行的任务,任务有关的代码需要写在次方法中
	public void start();//线程只创建并不会执行,必须调用start开启后才会执行任务

	public static void sleep(long millis); //让当前线程"休眠/暂停"多少毫秒
			这里的当前线程只指 Thread.sleep(1000)这句代码写哪个线程中,哪个线程就是当前线程
	public static Thread currentThread();//获取当前线程对象
			这里的当前线程是指 Thread.currentThread() 这句代码写哪个线程中,哪个线程就是当前线程


线程执行有优先级,优先级越高先执行机会越大(并不是一定先执行!!)。优先级用int的priority参数表示。
线程优先级最高为10,最低为1。默认为5 

2.创建新的线程的方式-继承

a.描述:
	将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例
b.分析创建的步骤:
	i.创建子类 继承 Thread
    ii.子类中重写run方法(在run中编写线程要执行的任务代码)
    iii.创建子类对象(实际上就是创建一个线程对象)
    iv. 调用线程对象的start方法(启动该线程)    
c.案例:
	//i.创建子类 继承 Thread
    public class MyThread extends Thread {
        //ii.子类中重写run方法(在run中编写线程要执行的任务代码)
        @Override
        public void run() {
            for (int i = 0; i < 50; i++) {
                System.out.println("子线程..."+i);
            }
        }
    }
	public class ThreadDemo02 {
    public static void main(String[] args) {
        // iii.创建子类对象(实际上就是创建一个线程对象)
        MyThread mt = new MyThread();
        //iv. 调用线程对象的start方法(启动该线程)
        mt.start();
        //主线程 不会等待子线程任务结束
        for (int i = 0; i < 50; i++) {
            System.out.println("主线程..."+i);
        }
    }
}

注意:
	a.我们可以给线程起名字,也可以使用默认的名字
    b.我们获取线程的名字时:
			建议使用通用方式: Thread.currentThread().getName();
			如果是子线程内部也可以直接调用getName()获取子线程的名字

创建新的线程方式二_实现方式

a.描述
    声明实现 Runnable 接口的类。该类然后实现 run 方法。
    然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递	并启动.
b.分析步骤:
	i.创建实现类 实现 Runnable接口(实际上接口中一个任务方法,run方法)
    ii.实现类重写run方法(run中编写具体的任务代码)
    iii.创建实现类对象(该实现类对象并不是线程对象,我们称为任务对象) 
    iv. 创建Thread对象,同时传入实现类对象
        public Thread(Runnable r);//带有线程任务的构造
	v. 启动该线程(调用线程对象的start方法)
c.代码实现
    //i.创建实现类 实现 Runnable接口(实际上接口中一个任务方法,run方法)
    public class MyRunnable implements Runnable {
        //ii.实现类重写run方法(run中编写具体的任务代码)
        @Override
        public void run() {
            //run中写任务代码
            for (int i = 0; i < 50; i++) {
                System.out.println("子线程..."+i);
            }
        }
    }
    
	public class TestThread {
        public static void main(String[] args) {
            //iii.创建实现类对象(该实现类对象并不是线程对象,我们称为任务对象)
            MyRunnable mr = new MyRunnable();
            //iv. 创建Thread对象,同时传入实现类对象
            Thread tt = new Thread(mr);
            //v. 启动该线程(调用线程对象的start方法)
            tt.start();

            //主线程不会等待子线程执行完毕
            for (int i = 0; i < 50; i++) {
                System.out.println("主线程..."+i);
            }
        }
    }

两种方式的优劣比较

两种创建线程的方式,实现方式比较好
    a.实现方式比较好,因为实现方式线程和任务是分开,是由程序员自己组合
    b.实现方式避免了Java单继承不足
    c.实现方式线程和任务是解耦的,继承方式线程和任务是耦合的
    d.对于线程池来说,我们需要的是Runnable的实现类,而不需要Thread的子类
综上所述: 在开发中我们建议使用实现方式(并不是说继承方式不对)   

匿名内部类简化创建线程方式

匿名内部类作用:
	可以快速创建一个类的子类对象或者一个接口的实现类对象
public class TestDemo {
    public static void main(String[] args) {
        //1.继承方式创建线程
        new Thread(){
            @Override
            public void run(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值