Java教程 多线程

一、Java教程 多线程
1.1 关于Java多线程的描述
进程和线程的区别:
1、一个应用程序至少一个进程,进程是指的完整的应用程序,每个进程拥有自己的内存管理,独立使用自己的数据,可以与其他进程通讯。
2、线程:一个应用程序(一个进程)中,可以有多个线程。公用内存管理,可以共享数据,轻量级,线程和线程之间可以直接进行通讯。
进程和线程用处?
并发程序中。并发,指同时会有很多的指令的请求。
单核cpu不存在真正的并发执行程序。只是切换调度而已。由于切换的较快,用户感觉不到
多核cpu存在真正的并发执行程序。
1.2 关于Java中创建多线程的方式:
1、创建子类:创建Thread的子类,重写run(); 方法,自定义执行逻辑
2、创建实现类:创建 Runnable 接口的实现,给Thread 类构造函数的参数进行实现呢。
一、通过创建 Thread 的子类,实现多线程的实例:
首先创建一个Test2 类继承(extends)Thread 类,并重写父类(Thread类)的run(); 方法,来进行多线程
Test2 类
/** * 多线程 继承Thread类 * @author Liu_Xiansheng */ public class Test2 extends Thread { private String name; public Test2(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("我是线程:"+this.name+",我在输出:" + i); } } public static void main(String[] args) { Test2 t1 = new Test2("A"); Test2 t2 = new Test2("B"); t1.start(); t2.start(); } }
Java控制台的输出结果:
我是线程:B,我在输出:0 我是线程:A,我在输出:0 我是线程:B,我在输出:1 我是线程:A,我在输出:1 我是线程:B,我在输出:2 我是线程:A,我在输出:2 我是线程:B,我在输出:3 我是线程:A,我在输出:3 我是线程:A,我在输出:4 我是线程:A,我在输出:5 我是线程:A,我在输出:6 我是线程:A,我在输出:7 我是线程:B,我在输出:4 我是线程:A,我在输出:8 我是线程:B,我在输出:5 我是线程:A,我在输出:9 我是线程:B,我在输出:6 我是线程:B,我在输出:7 我是线程:B,我在输出:8 我是线程:B,我在输出:9
你会发现 线程A 和 线程B 在同时进行运行,如果运行多次就会发现每次运行的结果都是不一样的,也就是说多线程的程序在同时运行;
二、通过创建实现类,也就是继承(implements)Runnable 类,重写Runnable 接口中的run(); 方法,通过构造函数把对象传给Thread 类
Test3 类:
/** * 继承接口Runnable接口,实例化对象,把实例化的对象传给Thread类 * @author Liu_Xiansheng */ public class Test3 implements Runnable { private String name; public Test3(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("我是线程:" + this.name + ",我在输出:" + i); } } public static void main(String[] args) { Test3 t1 = new Test3("A"); Test3 t2 = new Test3("B"); Thread t3 = new Thread(t1); Thread t4 = new Thread(t2); t3.start(); t4.start(); } }
Java控制台的输出:
我是线程:A,我在输出:0 我是线程:B,我在输出:0 我是线程:B,我在输出:1 我是线程:A,我在输出:1 我是线程:B,我在输出:2 我是线程:A,我在输出:2 我是线程:B,我在输出:3 我是线程:A,我在输出:3 我是线程:B,我在输出:4 我是线程:A,我在输出:4 我是线程:B,我在输出:5 我是线程:A,我在输出:5 我是线程:B,我在输出:6 我是线程:A,我在输出:6 我是线程:B,我在输出:7 我是线程:A,我在输出:7 我是线程:B,我在输出:8 我是线程:B,我在输出:9 我是线程:A,我在输出:8 我是线程:A,我在输出:9
1.3 Thread 和 Runnable 的区别:
实现Runnable接口比继承Thread类所具有的优势:
1、:适合多个相同的程序代码的线程去处理同一个资源
2、:可以避免Java中的单继承的限制
3、:增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4、:线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类
二、在多线程中常用方法/常用的关键字:
2.1 在多线程中常用的方法:
1、sleep();
休眠毫秒数,告诉运行到此处的线程,你停留的时间。
2、yield();
告诉系统,建议切换线程,但是切换后,系统有可能会重新切换回来。也就是说线程切换,系统并不是一定会听从建议。
3、join();
指等待线程终止。实现方法:启动线程后直接i但用。
join是Thread类的一个方法,启动线程后直接调用,即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。
Thread t = new AThread(); t.start(); t.join();
2.2在多线程中常用的关键字:
1、volatile 关键字:
可视化,如果在多线程中,其中数值发生改变了,并不是所有的线程都能看到,但是运用关键字volatile 后,数值发生改变的时候同时告诉别的线程,值改变后的结果
2、AtomicLong 关键字:
原子性。保证数值的原子性
三、关于Java中多线程资源共享的问题:
线程可以共享数据,但是会存在数据竞争,数据竞争可能会带来数据的错误(脏数据)。
锁与线程同步:保证线程安全
关于锁与线程同步的相关描述:
线程安全:多个线程在访问共享数据的时候,数据是安全的,如果导致共享的数据出现错误(或异常),那就是不安全的,如果多个线程没有共享数据则不存在线程安全问题。
如果说线程是安全的,则表示多个线程在同时操作本类的对象时,不会出现异常或数据错误。
synchronized 关键字
synchronized是同步锁,重量级锁,是互斥锁,可以保证绝对安全,但代价就是性能损失很大。
synchronized 可以修饰代码块,也可以修饰一个方法,当修饰一个方法的时候,是以this.作为锁。
常用的线程安全的方法:
Collections.synchronizedList:返回一个线程安全的list
Collections.synchronizedSet:返回一个线程安全的Set
Collections.synchronizedMap:返回一个线程安全的Map
如果代码不是原子操作,则都可能会出现数据竞争和脏数据。
四、线程池
创建线程,是比较耗费性能的。创建和销毁的过程是比较耗时的。
小编是:刘广法,转载请注明出处,网站地址:https://liuguangfa.com/