什么是线程?
过程想要执行工作就须要依赖线程。换句话说,就是过程中的最小执行单位就是线程,并且一个过程中至多有一个线程。
什么是多线程?
指在同一个过程中同时运行多个线程,如你开启QQ聊天,能够开启多个窗口。
提到多线程这里要说两个概念,就是串行和并行。
串行:其实是绝对于单条线程来执行多个工作来说的,当咱们下载多个文件时,在串行中它是依照肯定的程序去进行下载的,串行在工夫上是不可能产生重叠的。
并行:下载多个文件,开启多条线程,多个文件同时进行下载,这里是严格意义上的,在同一时刻产生的,并行在工夫上是重叠的。
多线程有三大个性:
原子性:一个操作或者多个操作,要么全副执行胜利,要么全都不执行。
可见性:当多个线程拜访同一个变量时,如果一个线程批改了这个变量的值,其余线程可能立刻看失去批改后的值。
有序性:程序执行的程序依照代码的先后顺序执行。
什么是并发编程?
所谓并发编程是指在一台处理器上“同时”解决多个工作。并发是在同一实体上的多个事件。多个事件在同一时间距离产生。
并发编程的目标:
- 让程序充分利用非计算机资源·
- 放慢程序响应速度(耗时工作、web服务器)
- 简化异步工夫的解决。
实现多线程的形式:
1) 继承 Thread
Thread类实质上是实现了Runnable接口的一个实例,代 表一个线程的实例。启动线程的惟一办法就是通过Thread 类的start()实例办法。
public class MyThread extends Thread {public void run() { System.out.println("MyThread.run()"); }} MyThread myThread1 = new MyThread();MyThread myThread2 = new MyThread();myThread1.start();myThread2.start();
2) 实现 Runnable 接口
如果本人的类曾经extends另一个类,就无奈间接extends Thread,此时,能够实现一个Runnable接口
public class MyThread extends OtherClass implements Runnable { public void run() {System.out.println("MyThread.run()"); } }
3)实现Callable接口通过FutureTask 包装器来创立 Thread 线程
public class CallableDemo implements Callable<String> { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(1); CallableDemo callableDemo = new CallableDemo(); Future<String> future = executorService.submit(callableDemo); System.out.println(future.get()); executorService.shutdown(); } @Override public String call() throws Exception { int a = 1; int b = 2; System.out.println(a + b); return "执行后果:" + (a + b); } }
线程的状态:
创立完的线程具备生命周期,从创立到死亡,两头还有一些其余状态的变动。
1)新建状态(New) : 线程对象被创立后,就进入了新建状态。例如,Thread thread = new Thread()。
2)就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创立后,其它线程调用了该对象的start()办法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
3)运行状态(Running) : 线程获取CPU资源后进行执行。须要留神的是,线程只能从就绪状态进入到运行状态。
4)阻塞状态(Blocked) : 阻塞状态是线程因为某种原因让出CPU资源,临时进行运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的状况分三种:
期待阻塞 – 通过调用线程的wait()办法,让线程期待某工作的实现。 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。 其余阻塞 – 通过调用线程的sleep()或join()或收回了I/O申请时,线程会进入到阻塞状态。当sleep()状态超时、join()期待线程终止或者超时、或者I/O处理完毕时,线程从新转入就绪状态。
5)死亡状态(Dead) : 线程顺利执行完了或者因异样退出了run()办法,该线程完结生命周期。
线程的罕用办法:
编号 | 办法 | 阐明 |
---|---|---|
1 | public void start() | 使该线程开始执行;Java 虚拟机调用该线程的 run 办法。 |
2 | public void run() | 如果该线程是应用独立的 Runnable 运行对象结构的,则调用该 Runnable 对象的 run 办法;否则,该办法不执行任何操作并返回。 |
3 | public final void setName(String name) | 扭转线程名称,使之与参数 name 雷同。 |
4 | public final void setPriority(int priority) | 更改线程的优先级。 |
5 | public final void setDaemon(boolean on) | 将该线程标记为守护线程或用户线程。 |
6 | public final void join(long millisec) | 期待该线程终止的工夫最长为 millis 毫秒。 |
7 | public void interrupt() | 中断线程。 |
8 | public final boolean isAlive() | 测试线程是否处于活动状态。 |
9 | public static void yield() | 暂停以后正在执行的线程对象,并执行其余线程。 |
10 | public static void sleep(long millisec) | 在指定的毫秒数内让以后正在执行的线程休眠(暂停执行),此操作受到零碎计时器和调度程序精度和准确性的影响。 |
11 | public static Thread currentThread() | 返回对以后正在执行的线程对象的援用。 |
进行线程:
进行线程是在多线程开发时很重要的技术点,把握此技术能够对线程的进行进行无效的解决。
在Java中有以下3种办法能够终止正在运行的线程:
- 应用退出标记,使线程失常退出,也就是当run办法实现后线程终止
- 应用stop办法强行终止线程,然而不举荐应用这个办法,因为stop和suspend及resume一样,都是作废过期的办法,应用他们可能产生不可意料的后果。
- 应用interrupt办法中断线程,但这个不会终止一个正在运行的线程,还须要退出一个判断才能够实现线程的进行。
多线程留神点:
多线程编程给咱们带来了很多的劣势,如充分利用处理器资源,并行做多件事件,然而在开发多线程利用时,咱们须要留神的问题有很多,比方线程同步、线程死锁等等。
- 线程平安
在单线程环境下,不加锁也没有线程平安和不平安问题,但多线程拜访时,须要线程同步拜访来保障线程平安,如同时有两个线程,线程A和线程B,对同一个账号金额进行批改操作,当采纳了加锁机制时,A线程在批改账号金额,B线程不能进行拜访,直到A线程读取完,B线程才可应用,这样就不会呈现数据不统一或者数据净化。 - 线程死锁
线程死锁是指多个线程竞争同一个资源,各自阻塞期待其余线程持有的锁,例如:
1.线程1锁住了A资源,而后尝试去对B资源加锁,同时线程2曾经锁住了B资源,再尝试对A加锁,为了彼此都能失去所需的资源而互相阻塞期待,从而产生了死锁。
更多java根底材料等你来拿!!!