Java多线程学习

发布时间 2023-09-18 22:14:41作者: 野风*

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();
    }
}