Java复习与学习笔记----进程和线程与同步(上)

简介: Java复习与学习笔记----进程和线程与同步

进程

进程:是正在运行的程序

是系统进行资源分配和调用的独立单位

每一个进程都有它自己的内存空间和系统资源

线程

线程:是进程中的单个顺序控制流,是一条执行路径

单线程:一个进程如果只有一条执行路径,称为单线程程序

多线程:一个进程如果有多条执行路径,称为多线程程序

多线程的实现方式

方式一:继承 Thread 类

定义一个类 MyThread 继承 Thread 类

在MyThread 类中重写run()方法

创建MyThread类的对象

启动线程

//**方式一:继承 Thread 类**
//        定义一个类 MyThread 继承 Thread 类
//        在MyThread 类中重写run()方法
//        创建MyThread类的对象
//        启动线程
public class MyThread extends Thread {
    @Override
    public void run() {
        for ( int i=0; i<100; i++ ) {
            System.out.println( this.getName() + " " + i );
        }
    }
    //重写run方法,run方法是用来封装被线程执行的代码
}
public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();//启动线程
        //调用run方法只是单纯调用方法,没有启动线程
        //调用start方法会导致线程开始执行,Java会调用此线程的run方法
    }
}

run方法封装线程执行的代码,直接调用,相当于普通方法的调用

start方法启动线程,然后由JVM调用此线程的run方法

设置和获取线程的名称

Thread类中设置和获取线程名称的方法:

void setName( String name ) : 将此线程的名称改为等于参数name

String getName() : 返回此线程的名称

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.setName("我的线程");
        System.out.println(myThread.getName());
    }
}
输出:
我的线程
public class Test {
    public static void main(String[] args) {
        //Thread.currentThread()返回对当前正在执行的线程对象的引用
        System.out.println( Thread.currentThread() );
    }
}
输出:
Thread[main,5,main]

通过构造方法设置线程的名称:

public class MyThread extends Thread {
    public MyThread() {
    }
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        for ( int i=0; i<100; i++ ) {
            System.out.println( this.getName() + " " + i );
        }
    }
}
public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread("我的线程");
        System.out.println( myThread.getName() );
    }
}
输出:
我的线程

线程调度

线程有两种调度模式:

分时调度模型:所有线程轮流使用CPU的使用权。平均分配每个线程占用CPU的时间片

抢占式调度模式:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么随机选择一个,优先级高的线程获取的CPU时间片相对多一些

Java使用的是抢占式模式调度

多线程执行具有随机性,因为谁抢到CPU的使用权不一定

Thread 类中设置和获取线程优先级的方法:

public final int getPriority(): 返回此线程的优先级

public final void setPriority( int newPriority ):更改此线程的优先级

线程的优先级具有范围:1-10,默认优先级为5

public class Test {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        System.out.println(myThread1.getPriority());
        MyThread myThread2 = new MyThread();
        myThread2.setPriority(10);
        MyThread myThread3 = new MyThread();
        myThread3.setPriority(1);
        System.out.println(myThread2.getPriority());
        System.out.println(myThread3.getPriority());
    }
}
输出:
5
10
1
System.out.println(Thread.MAX_PRIORITY);
System.out.println(Thread.MIN_PRIORITY);
输出:
10
1

线程优先级高仅仅表示获取CPU时间片的几率高,并不是优先级高的线程一定每次都可以抢到CPU时间片

线程控制

sleep
public class MyThread extends Thread {
    public MyThread() {
    }
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        for ( int i=0; i<100; i++ ) {
            System.out.println( this.getName() + " " + i );
            try {
                Thread.sleep(1000);//线程休眠一秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
join
public class Test {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();
        MyThread myThread3 = new MyThread();
        myThread1.start();
        try {
            myThread1.join();//线程一执行完成才会执行后面其他线程
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myThread2.start();
        myThread3.start();
    }
}
setDaemon
public class Test extends Thread {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();
        myThread1.setDaemon(true);
        myThread2.setDaemon(true);
        myThread1.start();
        myThread2.start();
        Test test = new Test();
        test.start();
        //当test执行结束,剩下的线程都为守护线程,会直接退出
    }
    @Override
    public void run() {
        for ( int i=0; i<10; i++ ) {
            System.out.println( "main" + " " + i );
        }
    }
}
public class MyThread extends Thread {
    @Override
    public void run() {
        for ( int i=0; i<100; i++ ) {
            System.out.println( this.getName() + " " + i );
        }
    }
}

线程的生命周期

多线程的实现方式二

创建线程的另一种方法:声明一个实现Runnable接口的类,实现run方法。然后可以分配类的实例,在创建Thread时作为参数传递,并启动线程。

实现多线程的方法二:

1.定义一个MyRunnable类实现Runnable接口

2.在MyRunnable类中重写run方法

3.创建MyRunnable类的对象

4.创建Thread类的对象,把MyRunnable对象作为构造方法的参数

5.启动线程

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for ( int i=0; i<10; i++ ) {
            System.out.println( i );
        }
    }
}
public class Test {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

给线程设置名字

thread.setName("我的线程");
System.out.println(thread.getName());

在创建线程对象时,给线程设置名字

Thread thread = new Thread(myRunnable, "我的线程~~");
        System.out.println(thread.getName());

多线程的实现方案:

1.继承Thread类

2.实现Runnable接口

相对于继承Thread类,实现Runnable接口,避免了Java单继承的局限性,适合多个相同程序的代码处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想


相关文章
|
5月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
269 1
|
5月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
287 1
|
6月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
6月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
安全 Java
深入理解Java并发编程:线程安全与性能优化
【2月更文挑战第22天】在Java并发编程中,线程安全和性能优化是两个重要的主题。本文将深入探讨这两个主题,包括线程安全的基本概念,如何实现线程安全,以及如何在保证线程安全的同时进行性能优化。
178 0
|
存储 安全 Java
深入理解Java并发编程:线程安全与锁机制
【5月更文挑战第31天】在Java并发编程中,线程安全和锁机制是两个核心概念。本文将深入探讨这两个概念,包括它们的定义、实现方式以及在实际开发中的应用。通过对线程安全和锁机制的深入理解,可以帮助我们更好地解决并发编程中的问题,提高程序的性能和稳定性。
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
334 1
|
安全 Java
Java中的并发编程:理解并发性与线程安全
Java作为一种广泛应用的编程语言,在并发编程方面具有显著的优势和特点。本文将探讨Java中的并发编程概念,重点关注并发性与线程安全,并提供一些实用的技巧和建议,帮助开发人员更好地理解和应用Java中的并发机制。
213 28
|
缓存 安全 Java
Java并发编程中的线程安全问题及解决方法
在Java编程中,线程安全是一个至关重要的问题,特别是在并发编程中。本文将探讨Java并发编程中常见的线程安全问题,包括数据竞争、死锁和内存可见性,并介绍了相应的解决方法,如使用同步锁、并发容器和原子类等技术,以确保多线程环境下程序的正确性和性能。
269 29
|
安全 Java 容器
Java一分钟之-并发编程:线程安全的集合类
【5月更文挑战第19天】Java提供线程安全集合类以解决并发环境中的数据一致性问题。例如,Vector是线程安全但效率低;可以使用Collections.synchronizedXxx将ArrayList或HashMap同步;ConcurrentHashMap是高效线程安全的映射;CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少场景;LinkedBlockingQueue是生产者-消费者模型中的线程安全队列。注意,过度同步可能影响性能,应尽量减少共享状态并利用并发工具类。
277 2