java多线程的讲解(上)

java多线程的讲解(上)

1.什么是进程?
2.什么是线程?
3.java如何实现多线程。
4.Thread类常见的方法。
5.线程安全问题如何解决。

1.什么是进程

进程是计算机中运行中的程序的实例。它是操作系统分配资源(如内存、CPU)并管理程序执行的基本单位。

目前操作系统都是支持多进程的,可以同时发执行多个进程,通过进程ID区分。单核CPU在同一时刻,只能有一个进程;宏观并行,围观串行。

2.什么是线程

线程,又称轻量级进程(Light Weight Process)。线程是进程中的一条执行路径,也是CPU的基本调度单位。若一个程序可同一时间执行多个线程,就是支持多线程的,一个进程优一个或多个线程组成,彼此之间完成不同的工作,同时执行,称为多线程。

3.Java创建多线程的方式

3.1继承Thread来完成多线程

1.创建一个线程类,继承Thread

2, 重写run方法,---写自己线程的任务代码

3,在主函数中创建线程对象,并开启线程,.start()

public class Test01 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();//实例化对象
        myThread.start();//调用线程主体
          for(int i=0;i<25;i++){
        System.out.println("main主体线程~~~~~~~~"+i);
    }
    }
}
public class MyThread extends Thread{ //Thread 表示线程类
    @Override
    public void run() { //重写run方法: 当线程启动后,会调用run方法体中的代码
        for(int i=0;i<25;i++){
            System.out.println("线程=========="+i);
        }
    }
}
​

3.2实现Runnable接口
public class Test02 {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();//实例化对象,
        Thread thread = new Thread(myRunnable);//实例化Thread类对象
        thread.start();//启动线程
          for(int i=0;i<25;i++){
        System.out.println("main主体线程~~~~~~~~"+i);
    }
    }
}
public class MyRunnable implements Runnable {//实现Runnable接口,作为线程的实现类
    @Override
    public void run() {//重写run方法,作为线程的操作主体
        for(int i=1;i<25;i++){
        System.out.println("线程B~~~~~~~~~~~~"+i);
        }
    }
}

是选用Thread类还是Runnable类

java只允许单继承,但是可以实现多接口,选择第一种继承Thread方式,那么就无法继承别的类,不利于扩充。

3.3实现Callable接口

暂无,待补充

4.Thread常见的方法

4.1

static Thread currentThread() 获取当前线程对象 String getName() 获取线程对象名字 void setName(String name) 修改线程对象名字

public class Test01 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();//实例化对象
        myThread.start();//调用线程主体
       //myThread.setName("A计划");    //修改线程对象名称
        //Thread.currentThread.setName("main计划");
    for(int i=0;i<25;i++){
        //获取当前线程对象名称,通用
        System.out.println("2"+Thread.currentThread().getName()+"main主体线程~~~~~~~~"+i);
    }
    }
}
public class MyThread extends Thread{ //Thread 表示线程类
    @Override
    public void run() { //重写run方法: 当线程启动后,会调用run方法体中的代码
        for(int i=0;i<25;i++){
            //this.getName获取当前前程的名称, ---该方法只能用于Thread的子类
            System.out.println("1"+this.getName()+"线程=========="+i);
        }
    }
}
​

4.2

static void sleep(long millis) 让当前线程休眠millis秒 static void yield() 让位方法,当前线程暂停,回到就绪状态,让给其它线程。

void setPriority(int newPriority) 设置线程优先级 1-10

void join() 将一个线程合并到当前线程中,当前线程受阻塞,加入的线程执行直到结束后,当前前程才会执行。

setDaemon(boolean on) on为true表示把线程设置为守护线程

public class Test03 {
    public static void main(String[] args) {
        MyThread2 myThread2 = new MyThread2();
        myThread2.start();
        myThread2.setName("第一"); 
        
        for(int i=1;i<25;i++){
            System.out.println("main~~~~~~~~~"+i);
        }
    }
}
public class MyThread2 extends Thread{
    @Override
    public void run() {
        for(int i=1;i<20;i++){
            try {
                //1休眠
                this.sleep(1000); //重写的方法,抛出的异常不能超过父类
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(this.getName()+"---------------"+i);
        }
    }
}
public class Test04 {
    public static void main(String[] args) {
        MyThread2 myThread21 = new MyThread2();
        MyThread2 myThread2 = new MyThread2();
        myThread2.setPriority(10);//2设置优先级
        myThread21.setPriority(1);//2设置优先级
        myThread2.start();  
        myThread21.start();
        
        for(int i=1;i<25;i++){
            System.out.println("main~~~~~~~~~"+i);
        }
    }
}
public class MyThread4 extends Thread{
    @Override
    public void run() {
        for(int i=1;i<20;i++){
            //Thread.yield();//3让位 当前线程暂停,回到就绪状态,让给其它线程。
            System.out.println(this.getName()+"---------------"+i);
        }
    }
}
public class Test05 {
    public static void main(String[] args) throws InterruptedException {
        MyThread2 myThread2 = new MyThread2();
        //4 myThread2.join();//myThread2线程加入了主线程当中,main线程需要等myThread2线程执行完才会执行
        myThread2.setDaemon(true);//5 设置myThread2线程为守护线程--后台线程。---当main线程执行完毕后,守护线程会结束
        myThread2.start();

        for(int i=1;i<25;i++){
            System.out.println("main~~~~~~~~~"+i);
        }
    }
}
public class MyThread5 extends Thread{
    @Override
    public void run() {
        for(int i=1;i<50;i++){
            System.out.println(this.getName()+"---------------"+i);
        }
    }
}

5.线程安全问题如何解决

当前卖票系统出现安全问题,解决线程安全问题

当多个线程共享一个资源时,可能会出现线程安全问题

如何解决线程安全问题?----使用锁。----》 凡是用锁 锁定的代码都是原子操作。

第一种自动锁:synchronized

第二种手动锁:Lock

public class Test07 {
    private static String[] arr= new String[2];
    private  static int index=0;
    public static void main(String[] args) throws InterruptedException {
//        MyThread7 my7 =new MyThread7();
//        Thread m1 =new Thread(my7,"商品A");
//        Thread m2 =new Thread(my7,"商品B");
//        Thread m3 =new Thread(my7,"商品C");
//        Thread m4 =new Thread(my7,"商品D");
//        m1.start();
//        m2.start();
//        m3.start();
//        m4.start();
        Thread t01 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (arr){
                if(arr[index]==null){
                    arr[index]="hello";
                    index++;
                }}
            }
        });

      Thread t02=  new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (arr){
                if(arr[index]==null){
                    arr[index]="world";
                    index++;
                }}
            }
        });
        t01.start();
        t02.start();
        t01.join();
        t02.join();
                        //arr.toString()
        System.out.println(Arrays.toString(arr));
    }
}
public class MyThread7 extends Thread{
    private int ticket=100;
    private Lock lo= new ReentrantLock();//手动上锁
    @Override
    public void run() {
        while (true){
​
//synchronized (this){  //自动上锁和释放锁
//            if(ticket>0){
//                ticket--;
//                System.out.println(Thread.currentThread().getName()+"卖了一张票,还剩"+ticket);
//            }else{
//                break;
//            }
//         }
lo.lock();//手动上锁
            if(ticket>0){
                ticket--;
                System.out.println(Thread.currentThread().getName()+"卖了一张票,还剩"+ticket);
            }else{
                break;
            }
lo.unlock();//手动解锁
}
    }
}

待续......

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值