Java创建线程的3种方式
线程有3种运行方式,分别为实现Runnable接口的run方法, 继承Thread类并重写run方法, 使用FutureTask方式。
方法1,继承Thread类,重写run方法
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("myThread running");
}
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
}
}
方法2,实现Runnable接口,实现类作为参数传给Thread
public class RunnableTask implements Runnable {
public void run() {
System.out.println("Runnable task is running");
}
public static void main(String[] args) {
new Thread(new RunnableTask()).start();
}
}
方法3,使用FutureTask方式
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallerTask implements Callable<String> {
public String call() throws Exception {
return "hello, from callerTask";
}
public static void main(String[] args) throws InterruptedException {
FutureTask<String> futureTask = new FutureTask<String>(new CallerTask());
new Thread(futureTask).start();
try{
String result = futureTask.get();
System.out.println(result);
}catch (ExecutionException e) {
e.printStackTrace();
}
}
}
一些多线程相关的小例子
1. 3个线程交替打印A,B,C 10次
class PrintABC {
private static final Object lock = new Object();
private static volatile int status = 1;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (status != 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("A ");
status = 2;
lock.notifyAll();
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (status != 2) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("B ");
status = 3;
lock.notifyAll();
}
}
});
Thread t3 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (status != 3) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("C ");
status = 1;
lock.notifyAll();
}
}
});
t1.start();
t2.start();
t3.start();
}
}
在Java中,当一个线程调用wait()
方法时,它会释放它持有的锁,并进入等待状态,直到另一个线程调用相同对象上的notify()
或notifyAll()
方法来唤醒它。当线程被唤醒时,它会重新获得锁并继续执行因此,wait()
方法会释放synchronized
的锁资源。
2.生产者消费者模型
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumerModel {
// 一个大小确定的队列把生产者跟消费者解耦
// 一个生产者线程, 一个消费者线程。
private static final Object lock = new Object();
private static final Queue<Integer> queue = new LinkedList<>();
private static final Integer MAX_SIZE = 10;
public static void main(String[] args) {
Thread producer = new Thread(()->{
for (int i=0; i<20; i++) {
synchronized (lock) {
while(queue.size() == MAX_SIZE) {
try {
lock.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.offer(i);
System.out.println("produced: " + i);
lock.notifyAll();
}
}
});
Thread consumer = new Thread(()->{
for(int i=0; i<20; i++) {
synchronized (lock) {
while (queue.isEmpty()) {
try {
lock.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer ret = queue.poll();
System.out.println("consumer: " + ret);
lock.notifyAll();
}
}
});
producer.start();
consumer.start();
}
}