说不上技术分享,只能算是学习记录
创建一个线程
Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
- 通过继承 Thread 类本身;
- 通过 Callable 和 Future 创建线程。
通过实现 Runnable
接口来创建线程
实现Runnable接口,重写run方法,调用start方法
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Thread2 implements Runnable{
@Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("t"+i); } }
public static void main(String[] args) { Thread2 t2=new Thread2(); new Thread(t2).start(); for (int i = 0; i <1000; i++) { System.out.println("now"+i); } } }
|
通过继承Thread来创建线程
继承Thread类,重写run方法,调用start方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Thread1 extends Thread{ @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("t"+i); } }
public static void main(String[] args) { Thread1 t1=new Thread1(); t1.start(); for (int i = 0; i <1000; i++) { System.out.println("now"+i); } } }
|
通过 Callable 和 Future
创建线程
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call()
方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable
对象,该 FutureTask 对象封装了该 Callable 对象的 call()
方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target
创建并启动新线程。
- 调用 FutureTask 对象的 get()
方法来获得子线程执行结束后的返回值。
创建线程的三种方式的对比
- 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了
Runnable 接口或 Callable 接口,还可以继承其他类。
- 使用继承 Thread
类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用
Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
线程的几个主要概念
在多线程编程时,你需要了解以下几个概念:
- 线程同步
- 线程间通信
- 线程死锁
- 线程控制:挂起、停止和恢复
Sleep
休眠,单位:毫秒
Yield
礼让,但不一定成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class TestYield { public static void main(String[] args) {
MyYield myYield=new MyYield(); new Thread(myYield,"a").start(); new Thread(myYield,"b").start(); } } class MyYield implements Runnable {
@Override public void run() { System.out.println(Thread.currentThread().getName() + "线程开始执行"); Thread.yield(); System.out.println(Thread.currentThread().getName() + "线程停止执行"); } }
|
Join
强制执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class TestJoin implements Runnable{ public static void main(String[] args) throws InterruptedException { TestJoin testJoin=new TestJoin(); Thread thread=new Thread(testJoin); thread.start();
for (int i = 0; i < 500; i++) { if(i==200) { thread.join(); } System.out.println("main"+i); } }
@Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("插队"+i); } } }
|
同步
synchronized关键字
Lock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| import java.util.concurrent.locks.ReentrantLock;
public class TestLock { public static void main(String[] args) { TestLock2 testLock2=new TestLock2(); new Thread(testLock2).start(); new Thread(testLock2).start(); new Thread(testLock2).start(); } }
class TestLock2 implements Runnable { int ticketNum = 10;
private final ReentrantLock lock = new ReentrantLock();
@Override public void run() { while (true) { try { lock.lock(); if (ticketNum > 0) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(ticketNum--); } else { break; } } finally { lock.unlock(); } } } }
|
线程池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class TestPool { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); service.shutdown(); } }
class MyThread implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName()); } }
|
参考
https://www.bilibili.com/video/BV1V4411p7EF