乐趣区

关于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<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 根底材料等你来拿!!!
退出移动版