一、多线程的几种实现方式:
- 使用Thread类
1. 定义一个java.lang.Thread的子类,必须重写其中的run方法:
public class MyThread extends Thread {
@Override
public void run() {
System.out.println(this.getName()); // 打印线程名称
}
}
2. 在需要的地方,创建一个子类对象,并调用该对象的start方法:
public class testDemo {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
- 使用Runnable接口
1. 定义一个Runnable接口的实现类,实现接口中的run方法:
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()); // 打印线程名称
}
}
2. 可以匿名创建一个Thread对象,传入一个实现Runnable接口的对象,再调用start方法:
public class testDemo {
public static void main(String[] args) {
Runnable thread = new MyThread();
new Thread(thread).start();
}
}
- 使用匿名内部类的方式创建新的线程
--> 用于一次性使用的情况,避免创建一个新的类:
public class testDemo {
public static void main(String[] args) {
new Thread() {
// 在匿名内部类中重写run方法
@Override
public void run() {
System.out.println(this.getName()); // 打印线程名称
}
}.start();
}
}
二、线程同步的几种实现方式:
在使用多线程时,为了线程安全,我们一般需要对部分代码进行同步处理,以下是Java中实现线程同步的几种方式:
注意以下几种实现方式的锁对象必须是唯一的!
- 使用同步代码块
通过synchronized关键字,传入一个锁对象,可实现同步代码:
public void run() {
// 此处需要传入一个锁对象,可以是this,也可以专门创建一个成员变量Object作为锁对象
synchronized (this) {
System.out.println("Thread Started");
}
}
- 使用同步方法
把需要实现同步的代码整合到一个方法中,再用synchronized来修饰这个方法:
@Overridepublic void run() {
this.myMethod();
}
public synchronized void myMethod(){ // 添加一个synchronized关键字
System.out.println(Thread.currentThread().getName());
}
- 使用Lock接口的实现类ReentrantLock类
即在同步代码执行前后分别给代码加锁解锁:
public class MyThread implements Runnable {
Lock l = new ReentrantLock();
@Override
public void run() {
l.lock(); // 同步代码执行前锁住进程
System.out.println(Thread.currentThread().getName());
l.unlock(); // 同步代码执行后解锁进程
}
}
官方推荐使用try...catch...finally的写法:
public class MyThread implements Runnable {
Lock l = new ReentrantLock();
@Override
public void run() {
l.lock(); // 同步代码执行前锁住进程
try {
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace(e);
} finally { // finally中的代码必定会执行,无论代码是否出现异常,锁对象都能释放掉
l.unlock(); // 同步代码执行后解锁进程
}
}
}