Java极速入门系列-第六章 Java多线程、合集框架(Collection 接口、泛型)

本文深入介绍了Java中的多线程概念,包括线程的创建、状态、调度和同步机制,如重入锁。此外,还详细讲解了Java集合框架,特别是Collection接口、泛型及其应用,如ArrayList、LinkedList、HashSet、TreeSet等,并探讨了泛型的优势和使用技巧。
摘要由CSDN通过智能技术生成

1.多线程

1.1线程和进程

进程:计算机正在运行的一个独立的应用程序

线程:是组成进程的基本单位

一个进程由一个或多个线程组成

进程是独享内存空间,线程是共享内存空间(线程执行是相互独立的)

单独的线程无法执行,必须依赖于进程才能执行

多线程:在一个进程中,多个线程同时执行,其实是所有线程轮流交替占用CPU资源,中间过程较短,所以说多个线程同时执行

main方法就是一个单线程,所以先输出循环Test,再输出循环Test2

在这里插入图片描述

线程是用来执行任务的,每个线程对象都需要绑定一个任务

Java 中线程是对象,任务也是对象

1.2Java中线程的使用

继承Thread类 ,实现Runnable接口

1.继承Thread类

在这里插入图片描述

在这里插入图片描述

两个线程交替占用cpu运行

继承Thread类将任务和线程绑定了,这个线程就只能做这种事,解耦合度高

2.实现Runnable接口

Runnable 接口就是用来描述任务的,实现 run 方法来描述任务

实现线程和任务的解耦合,单独定义一个类实现 Runnable接口作为任务,创建 Thread 对象之后再把任务整合进去

定义任务

package test;
public class MyRunnable implements Runnable {
   
    @Override
    public void run() {
   
        for (int i = 0; i < 100; i++) {
   
            System.out.println("===Runnable===");
        }
    }
}

创造线程,执行任务

package test;
public class Test {
   
    public static void main(String[] args) {
   
		//创建任务
        MyRunnable myRunnable = new MyRunnable();
		//创建线程
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

1.3线程的状态

  • 创建状态 相当于(Thread thread = new Thread(myRunnable);)
  • 就绪状态 相当于(thread.start();)
  • 运行状态 (交替执行时 ,正在执行的线程就属于运行状态)
  • 阻塞状态 (交替执行时 ,其他线程占用cpu执行时,此时此线程属于阻塞状态)
  • 终止状态
    在这里插入图片描述

1.4线程调度

1.线程休眠

让当前线程暂停执行,运行状态->阻塞状态,让出 CPU 资源,sleep(long millis) 单位毫秒,创建出的线程都可以调用sleep,主线程不行

package test;
public class MyThread extends Thread {
   
    @Override
    public void run() {
   
        for (int i = 0; i < 100; i++) {
   
            if(i==5){
   
                try {
   
                    sleep(1000);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            }
            System.out.println("---MyThread---");
        }
    }
}
//外部做休眠
package test;
public class Test {
   
    public static void main(String[] args) {
   
        MyThread myThread = new MyThread();
        try {
   
            myThread.sleep(1000);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        myThread.start();
        for (int i = 0; i < 100; i++) {
   
            System.out.println("---main---");
        }
    }
}

主线程调用sleep方法 Thread.currentThread().sleep(1000);

package test;
public class Test {
   
    public static void main(String[] args) {
   
        for (int i = 0; i < 100; i++) {
   
            if(i==5){
   
                try {
   
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException
                        e) {
   
                    e.printStackTrace();
                }
            }
            System.out.println("---main---");
        }
    }
}

2.线程合并

将指定的某个线程加入到当前线程中,合并为一个线程。join()

A 和 B,B.join() 表示当前开始 CPU 资源被 B 独占,A 进入阻塞状态,B 执行完毕,A 才能继续继续执行。

package test;
public class JoinRunnable implements Runnable {
   
    @Override
    public void run() {
   
        for (int i = 0; i < 100; i++) {
   
            System.out.println(i + "------JoinRunnable");
        }
    }
}

package test;
public class Test {
   
    public static void main(String[] args) {
   
        JoinRunnable joinRunnable = new JoinRunnable();
        Thread thread = new Thread(joinRunnable);
        thread.start();
        for (int i = 0; i < 100; i++) {
   
            if(i == 10){
   
                try {
   
                    thread.join();
                } catch (InterruptedException
                        e) {
   
                    e.printStackTrace();
                }
            }
            System.out.println(i + "======main");
        }
    }
}

当运行到9时,从10开始都是执行joinRunnable,知道joinRunnable执行完成

join有个方法重写

join(long millis)

B.join() 表示当前开始 CPU 资源被 B 独占,A 进入阻塞状态,在 millis 时间内 B 独占 CPU 资源进行执行,但是时间一到无论 B 是否执行完毕,都会释放 CPU 资源,和 A 继续交替执行。

package test;
public class JoinRunnable implements Runnable {
   
    @Override
    public void run() {
   
        for (int i = 0; i < 20; i++) {
   try {
   
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
            System.out.println(i + "------ JoinRunnable");
        }
    }
}
package test;
public class Test {
   
    public static void main(String[] args) {
   
        JoinRunnable joinRunnable = new JoinRunnable();
        Thread thread = new Thread(joinRunnable);
        thread.start();
        for (int i = 0; i < 100; i++) {
   
            if(i == 10){
   
                try {
   
                    thread.join(3000);
                } catch (InterruptedException
                        e) {
   
                    e.printStackTrace();
                }
            }
            System.out.println(i + "======main");
        }
    }
}

3.线程礼让

在某个特定的时间点,让线程暂停抢占 CPU 资源的行为,运行状态 -> 阻塞状态,yield(),当这个礼让之后继续抢占资源

线程1

package test;
public class YieldThread1 extends Thread {
   
    @Override
    public void run() {
   
        for (int i = 0; i < 10; i++) {
   
            if(i==5){
   
                Thread.currentThread().yield();
            }
            System.out.println(Thread.currentThread().getN
                    ame() + "------" + i);
        }
    }
}

线程2

package test;
public class YieldThread2 extends Thread {
   
	@Override
	public void run() {
   
		for (int i = 0; i < 10; i++) {
   
System.out.println(Thread.currentThread().getName() + "------" + i);
}
}
}

运行

package test;
public class Test {
   
    public static void main(String[] args) {
   
        YieldThread1 thread1 = new YieldThread1();
        thread1.setName("线程A");
        YieldThread2 thread2 = new YieldThread2();
        thread2.setName("线程B");
        thread1.start();
        thread2.start();
    }
}

结果,在id=5 ,A礼让了B
在这里插入图片描述

1.5线程同步

多个线程同时访问某个资源时,不是同时对资源进行访问修改,而是顺序执行。

多个线程同时访问共享资源时,可能会存在数据错误的情况,如何解决?

通过线程同步,多个线程不是同时访问数据,而是顺序访问。

1.synchronized 修饰实例方法

//当上一个线程走完时,才会走下一个线程
package test;
public class Account implements Runnable {
   
    private static int num;
    @Override
    public synchronized void run() {
   
        try {
   
            Thread.currentThread().sleep(1);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        num++;
        System.out.println(Thread.currentThread().getN
                ame() + "是当前的第" + num + "位访客");
    }
}
package test;
public class Test {
   
    public static void main(String[] args) {
   
        Account account = new Account();
        Thread thread1 = new Thread(account,"线 程A");
                Thread thread2 = new Thread(account,"线程B");
                thread1.start();
        thread2.start();
    }
}

2.synchronized 修饰静态方法

package test;
public class Test2 {
   
    public static void main(String[] args) {
   
        for (int i = 0; i < 5; i++) {
   
            Thread thread = new Thread(new Runnable(){
   
                @Override
                public void run() {
   
                    Test2.test();
                }
            });
            thread.start();
        }
    }
    public static  void test(){
   
        System
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你我有猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值