Java多线程基础理解

2021-3-22 Java多线程

并行与并发

并行:指两个或多个事件同时发生    如:边打电话边吃饭

并发:指两个或多个事件交替执行    如:吃一口饭,喝一口汤,再吃一口饭

线程与进程

进程:一个内存中运行的应用程序,数据存放空间是独立的,至少有一个线程。

线程:进程中的执行单元,堆空间是共享的,栈空间是独立的,线程的资源消耗比进程的小的多。

一个进程中可以有多个线程,这个程序被称为多线程程序。

多线程的随机性:一个进程中的多个线程是并发运行的,执行顺序由cpu随机执行,无法干涉。

线程创建的过程 

创建一个类继承Thread,并且重写thread当中的run方法

在主方法中创建对象,用start方法调用该对象。

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(getName()+i);
        }
    }
}
 /*创建线程Thread*/
        MyThread myThread = new MyThread();
        myThread.start();

使用Runnable接口方式创建线程

创建一个类实现Runnable接口,并且重写当中的run方法

在主方法中创建对象,并将该对象传入新建的Thread对象当中。

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}
//创建runnable线程
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();

好处:可以继续继承别的类,实现其他接口,任务可以线程共享

使用匿名内部类创建

//使用匿名内部类创建
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+i);
                }
            }
        });
        thread1.run();

线程安全

案例:卖票时多线程共享数据,造成了资源抢夺,出现重复卖票的情况

解决方法:对共享资源进行加锁处理

加锁的方式分为两种,一种是synchronized加锁,另一种是lock加锁

public class TicketTestImpl implements Runnable{
    private int ticket = 100;
    @Override
    public void run() {
        while(true){
            //对资源信息进行加锁处理
            synchronized (new Object()){//需要传入一个唯一的值,类似object,this
                if(ticket>0){
                    System.out.println(Thread.currentThread().getName()+"卖了:"+ticket);
                    ticket--;
                }else{
                    System.exit(0);
                }
            }

        }
    }
}

或者可以将锁对象放到方法前,(相当于synchronized传入了this,静态对象则传入当前对象的字节码)

public synchronized void TicketMethod(){
        if(ticket>0){
            System.out.println(Thread.currentThread().getName()+"卖了:"+ticket);
            ticket--;
        }else{
            System.exit(0);
        }
    }

Lock方式加锁

Lock l =  new ReentrantLock();
    @Override
    public void run() {
        while(true){
                //加锁
                l.lock();
                TicketMethod();
                //解锁
                l.unlock();
            }
        }

线程状态

线程等待Thread.wait(),随机唤醒一个线程Thread.notify(),唤醒所有线程Thread.notifyall()

synchronized传入的锁对象必须是相同

Object obj = new Object();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj){
                    System.out.println("顾客:老板我要吃饺子");
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("顾客:饺子真好吃");
                }
            }
        }){

        }.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj){
                    try {
                        Thread.sleep(3000);
                        System.out.println("老板:饺子做好了");
                        obj.notify();
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

线程池

public static void main(String[] args) {
        //1.使用线程池工厂Executors提供的静态方法newFixedThreadPool
        // 生产一个制定线程数量的线程池
        ExecutorService ex = Executors.newFixedThreadPool(2);
        //2.调用线程池ExecutorService中的方法submit,传递线程任务,执行线程任务
        // 相当于new Thread(new Runnable(){}).start();
        ex.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"线程任务1执行了!");
            }
        });
        ex.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"线程任务2执行了!");
            }
        });
        ex.shutdown();//销毁线程
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值