Java之多线程入门:
想要了解Java多线程我们先要了解计算机中的几条概念?
1.并发:两个或多个时间同一时刻发生(交替)
2.并行:两个或多个时间在同一时间段内发生
3.线程:一个应用正在运行的程序,进程内部的执行单元,执行路径
4.进程:正在运行的程序,一个进程中最少有一个线程,也可以多条线程,有独立的内存空间
我们看到计算机一边放音乐,一边还能玩游戏,感觉是同时进行,实际上是CPU在一直切换,CPU每秒可以进行几万次的切换,就是交替着执行,我们感觉是在并行,其实则是并发,单核的计算机操作都是并发,只有双核以及四核的才会并行.进程则是我们正在运行的程序,一个进程至少有一个或多个线程,比如我们的迅雷下载,他是有多条线程同时进行,CPU不停地在几条线程之间互相切换,如果想要让一个应用执行的够快,则需要创建多条线程,CPU的切换具有随机性,创建多条线程会增大CPU切换到这个应用的几率,所以就有了多线程的概念.
一.首先创建一条多线程的入门:
public class MyThead {
public static void main(String[] args) {
new newThead().start();
for (int i = 0; i < 1000; i++) {
System.out.println("主方法运行");
}
}
}
class newThead extends Thread{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程开启");
}
}
}
这是一个简单的多线程入门,开启线程的方式有三种(加上lambda表达式有说四种的):
1.继承Thread类: 由于此方法开启的线程不能加入到线程池里,所以很少用到此类方法.
2.实现Runnable:建议使用此种方法,实现接口更加符合开发的高内聚低耦合的思想,
3.实现Callable:基础用到不多,不多解释.
二.说下什么是线程安全:
线程安全就是如果有多个线程同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的果是一样的,而且其他的变量的值和预期的是一样的,就是线程安全的.Java中提供了一套解决线程安全问题的机制,可以叫做锁机制,准确的叫同步机制,使用这种机制,就可以保证数据的同步性.
三.3种方式解决线程安全的问题:
1.同步代码块: synchronized(锁对象){
需要进行同步操作的代码
}
class newThead implements Runnable{
@Override
public void run() {
synchronized (newThead.class){
System.out.println("A");
}
}
}
2.同步方法: 方法被synchronized关键字修饰,方法里面填写可能出现线程安全问题的代码在run方法里面调用此方法即可
class newThead implements Runnable{
@Override
public void run() {
test();
}
public synchronized void test(){
System.out.println("A");
}
}
3.Lock锁: 在类中new一个Lock对象
Lock lock=new ReentrantLock();在可能出现线程安全问题代码的开头开启Lock.lock方法在可能出现线程安全问题代码的结尾开启Lock.unlock方法
class newThead implements Runnable{
Lock lock=new ReentrantLock();
@Override
public void run() {
lock.lock();
System.out.println("A");
lock.unlock();
}
}
四.线程的六种状态
NEW(新建): 尚未启动的线程处于这种状态
RUNNABLE(可运行):正在Java虚拟机中执行的线程正处于这种状态
BLOCKED(锁阻塞):受阻塞并等待某个监视器锁的线程正处于这种状态
WAITING(无限等待):无限期的等待另一个线程来执行某一特定的线程处于这种状态
TIMED WAITING(计时等待): 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态
TERMINATED(被终止): 已退出的线程处于这种状态
无限等待的线程只能被其他线程唤醒,而计时等待的线程可以被其他的线程唤醒,也可以的等待自己的沉睡时间一到自动醒来.
五.多线程的几种方法
wait:线程进入无限等待状态,只能被拥有同个锁的线程唤醒
sleep:线程进入计时等待状态
notify:唤醒单个在无限等待或者计时等待状态的线程
notifyAll:唤醒所有无限等待或者计时等待状态的线程
notify方法在唤醒线程时具有随机性,wait和notify/notifyAll方法就是指线程的等待唤醒机制,继而达到线程之间的通信.sleep方法调用之后,并没有释放锁。使得线程仍然可以同步控制,sleep不会让出系统资源,wait方法会释放锁.出让系统资源.
六.线程池的入门
线程池的创建入门:
1.获取线程对象
ExecutorService 线程池对象=Executors.newFixedThreadPool(最大线程数量);
2.线程任务对象
MyRunnable 线程对象=new MyRunnable();
3.提交
线程池对象.submit(线程对象);
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyThead {
public static void main(String[] args) {
//1.获取线程对象
ExecutorService service= Executors.newFixedThreadPool(5);
//2.线程任务对象
newThead nt1=new newThead();
newThead nt2=new newThead();
newThead nt3=new newThead();
//3.提交
service.submit(nt1);
service.submit(nt2);
service.submit(nt3);
}
}
class newThead implements Runnable{
@Override
public void run() {
System.out.println("A");
}
}
提示:一般线程池我们不会关闭