java多线程合并成串行_java多线程与并发编程

什么是线程?

进程想要执行任务就需要依赖线程。换句话说,就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。

什么是多线程?

指在同一个进程中同时运行多个线程,如你开启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 {

public static void main(String[] args) throws ExecutionException, InterruptedException {

ExecutorService executorService = Executors.newFixedThreadPool(1);

CallableDemo callableDemo = new CallableDemo();

Future 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基础资料等你来拿!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值