多线程基础(一)
最近读了高洪岩老师的《Java多线程编程核心技术》一书,打算记录下多线程的基础知识点,也算对本书的一个读后感了。目前打算分四五篇博文进行记录。
第一篇主要是记录线程的概念,创建,常用的基础方法等。
1. 什么是线程?
通常我们所说线程是进程的最小单位。那么问题来了,什么是进程呢?进程就是操作系统结构的基础;是一次程序的执行;等等,他是系统进行资源分配和调度的一个独立单位。
2. 创建线程的4种方式
1、继承Thread类 2、实现Runnable接口 3、实现Callable接口重写call()方法(注:需要搭配Future) 4、使用线程池(例:Executor框架)
3. 下面讲解线程中的各方法使用
3.1 currentThread()方法
作用:返回代码段正在被哪个线程调用的信息。
示例:
public class CreateThreandA implements Callable { @Override public Object call() throws Exception { System.out.println("run方法:"+Thread.currentThread().getName()); return "ok"; } public static void main(String[] args) throws ExecutionException, InterruptedException { CreateThreandA threandA = new CreateThreandA(); FutureTask futureTask = new FutureTask(threandA); ExecutorService executorService = Executors.newFixedThreadPool(1); executorService.submit(futureTask); executorService.shutdown(); System.out.println("mian方法:"+Thread.currentThread().getName()); } } //执行结果 mian方法:main run方法:pool-1-thread-1
3.2 isAlive()方法
作用:判断当前线程是否处于活动状态(true活动状态、false线程终止)
示例:
public class CreateThreandA extends Thread { @Override public void run() { System.out.println("begain···"); System.out.println("threandA="+this.isAlive()); System.out.println("end···"); } public static void main(String[] args) throws InterruptedException { CreateThreandA threandA = new CreateThreandA(); threandA.start(); threandA.join(); System.out.println("threandA="+threandA.isAlive()); } } //执行结果 begain··· threandA=true end··· threandA=false
3.3 sleep()方法
作用:在指定的毫秒数内让当前正在运行的线程休眠(注:不会释放锁)
示例:
public class CreateThreandA extends Thread { private static Logger logger = LoggerFactory.getLogger(CreateThreandA.class); @Override public void run() { System.out.println("begain···"+System.currentTimeMillis()); try { Thread.sleep(2000); System.out.println("休眠中···"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end···"+System.currentTimeMillis()); } public static void main(String[] args) throws InterruptedException { CreateThreandA threandA = new CreateThreandA(); threandA.start(); } } //执行结果(相差2秒) begain···1541213244502 休眠中··· end···1541213246504
3.4 getId()方法
作用:获取线程的唯一标识
示例:
public class CreateThreandA extends Thread { private static Logger logger = LoggerFactory.getLogger(CreateThreandA.class); @Override public void run() { } public static void main(String[] args) throws InterruptedException { CreateThreandA threandA = new CreateThreandA(); threandA.start(); System.out.println(Thread.currentThread().getName()+"--标识="+Thread.currentThread().getId()); System.out.println(threandA.getName()+"--标识="+threandA.getId()); } } //执行结果 main--标识=1 Thread-0--标识=11
3.5 interrupted()
作用:测试当前线程是否已经中断(具有清除状态的功能)
public class CreateThreandA { public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt(); System.out.println(Thread.interrupted()); System.out.println(Thread.interrupted());//清除了true的状态 } } //执行结果 true false
3.6 isInterrupted()
作用:测试线程是否已经中断(不会清楚状态)
public class CreateThreandA { public static void main(String[] args) throws InterruptedException { System.out.println(Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); System.out.println(Thread.currentThread().isInterrupted()); System.out.println(Thread.currentThread().isInterrupted()); } } //执行结果 false true true
3.7 stop()
作用:暴力停止线程(已经废弃,不推荐使用、所以我也不做示例了)
3.8 suspend()和resume()
作用:suspend()暂停线程;resume()恢复线程 (注:这两种也已废弃,不做示例演示)
3.9 yield()
作用:放弃当前CPU资源,将它让给其他任务去占用CPU执行时间
public class CreateThreandA extends Thread { private int count = 0; public void run(){ long time1 = System.currentTimeMillis(); for (int i=0;i<50000000;i++){ Thread.yield(); count+=i; } long time2 = System.currentTimeMillis(); System.out.println("耗时:"+(time2-time1)); } public static void main(String[] args){ CreateThreandA threandA = new CreateThreandA(); threandA.start(); } }
3.10 setPriority()
作用:设置线程的优先级(注:优先级只能是1~10、否则会报错,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。)
public class CreateThreandA extends Thread { CreateThreandA(String name){ super(name); } public void run(){ System.out.println(this.getName()); } public static void main(String[] args){ CreateThreandA threandA = new CreateThreandA("A"); CreateThreandA threandB = new CreateThreandA("B"); CreateThreandA threandC = new CreateThreandA("C"); CreateThreandA threandD = new CreateThreandA("D"); threandA.setPriority(1); threandB.setPriority(2); threandC.setPriority(3); threandD.setPriority(10); threandA.start(); threandB.start(); threandC.start(); threandD.start(); } }
3.11 wait()
作用:线程等待(释放锁)
public class CreateThreandA extends Thread { private Object lock; CreateThreandA(String name,Object lock){ super(name); this.lock=lock; } public void run(){ try { synchronized (lock){ System.out.println("上锁"); lock.wait(); System.out.println("开锁"); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args){ Object lock = new Object(); CreateThreandA threandA = new CreateThreandA("A",lock); CreateThreandA threandB = new CreateThreandA("B",lock); threandA.start(); threandB.start(); } } //执行结果 上锁 上锁
3.12 notify()、notifyAll()
作用:释放锁(notify随机释放一个锁、notifyAll释放全部锁)
开锁 public class CreateThreandB extends Thread { private Object lock; CreateThreandB(String name, Object lock){ super(name); this.lock=lock; } public void run(){ try { synchronized (lock){ lock.notify(); } } catch (Exception e) { e.printStackTrace(); } } } 上锁 public class CreateThreandA extends Thread { private Object lock; CreateThreandA(String name,Object lock){ super(name); this.lock=lock; } public void run(){ try { synchronized (lock){ System.out.println("上锁"); lock.wait(); System.out.println("开锁"); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args){ Object lock = new Object(); CreateThreandA threandA = new CreateThreandA("A",lock); CreateThreandA threandB = new CreateThreandA("B",lock); CreateThreandB threand = new CreateThreandB("C",lock); threandA.start(); threandB.start(); threand.start(); } } //执行结果(印证随机开一个锁) 上锁 开锁 上锁 notifyAll开全部锁 修改开锁类 lock.notifyAll(); //执行结果 上锁 上锁 开锁 开锁
3.13 join()
作用:等待线程对象销毁(如果子线程需要较长时间执行,主线程往往会提前执行完毕,如果想等待子线程时可以采用join)
package com.chenpt.thread; import org.omg.Messaging.SYNC_WITH_TRANSPORT; /** * @Author: chen * @Description: * @Date: created in 2018/11/3 * @Modified By: */ public class CreateThreandA extends Thread { private Object lock; CreateThreandA(String name,Object lock){ super(name); this.lock=lock; } public void run(){ try { System.out.println("休眠"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Object lock = new Object(); CreateThreandA threandA = new CreateThreandA("A",lock); threandA.start(); threandA.join(); System.out.println("我是主线程,我应该等等子线程"); } } //执行结果 休眠 我是主线程,我应该等等子线程 (如果不加join,则主线程先输出)
先总结这些基础方法,下面注重讲解进阶知识