继承Thread类实现多线程
package com.example.demo1;
// 方式一:继承Thread类
class MyThread extends Thread {
// 重写run()方法(线程执行体)
@Override
public void run() {
// 获取当前线程名称(通过父类方法)
System.out.println("当前线程名(继承Thread): " + getName());
// 线程休眠示例(暂停200ms)
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出线程优先级
System.out.println(getName() + " 优先级: " + getPriority());
}
}
public class ThreadDemo {
public static void main(String[] args) {
// 创建线程对象
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
// 设置线程名称(方式1:通过setName)
t1.setName("线程A");
// 设置线程名称(方式2:通过构造方法,需在MyThread中添加带参构造)
t2 = new MyThread() {{ setName("线程B"); }};
// 设置优先级(范围1-10,默认5)
t1.setPriority(Thread.MAX_PRIORITY); // 10
t2.setPriority(Thread.MIN_PRIORITY); // 1
// 启动线程(JVM会调用run())
t1.start();
t2.start();
// 主线程输出当前线程信息
System.out.println("主线程名: " + Thread.currentThread().getName());
}
}
实现Runnable接口
package com.example.demo1;
// 方式二:实现Runnable接口(推荐,避免单继承限制)
class MyRunnable implements Runnable {
@Override
public void run() {
// 通过Thread.currentThread()获取当前线程对象
Thread current = Thread.currentThread();
System.out.println("当前线程名(Runnable): " + current.getName());
// 线程休眠示例(暂停300ms)
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
// 创建Runnable任务
MyRunnable task = new MyRunnable();
// 使用Thread(Runnable target)构造线程
Thread t1 = new Thread(task);
// 使用Thread(Runnable target, String name)构造带名称的线程
Thread t2 = new Thread(task, "线程C");
t1.start();
t2.start();
}
}
实现Callable接口
package com.example.demo1;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
// 方式三:实现Callable接口(可获取返回值)
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception { // 可声明异常
Thread.sleep(100); // 模拟耗时操作
return Thread.currentThread().getName() + " 执行完成";
}
}
public class CallableDemo {
public static void main(String[] args) throws Exception {
// 创建Callable任务
MyCallable callable = new MyCallable();
// 用FutureTask包装Callable(桥接Callable和Thread)
FutureTask<String> futureTask = new FutureTask<>(callable);
// 启动线程(FutureTask本身是Runnable)
new Thread(futureTask, "线程D").start();
// 获取结果(阻塞直到完成)
String result = futureTask.get();
System.out.println("Callable返回结果: " + result);
}
}
守护线程示例
package com.example.demo1;
class DaemonTask implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("守护线程运行中...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class DaemonThreadDemo {
public static void main(String[] args) throws InterruptedException {
Thread daemonThread = new Thread(new DaemonTask());
// 设置为守护线程(必须在start()前调用)
daemonThread.setDaemon(true);
daemonThread.start();
// 主线程运行2秒后结束
Thread.sleep(2000);
System.out.println("主线程结束,JVM退出");
}
}
线程同步
package com.example.demo1;
public class a {
// 示例1:同步代码块解决线程安全问题
static class TicketRunnableWithSyncBlock implements Runnable {
private int ticket = 10; // 共享的剩余票数
@Override
public void run() {
while (ticket > 0) {
// 同步代码块:锁对象是当前Runnable实例(保证多个线程共享同一把锁)
synchronized (this) {
if (ticket > 0) { // 再次检查防止超卖(避免线程唤醒后条件已变化)
System.out.println(Thread.currentThread().getName()
+ " 卖出1张票,剩余:" + (--ticket));
}
}
try {
Thread.sleep(10); // 模拟操作耗时,放大线程安全问题
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 示例2:同步方法解决线程安全问题
static class TicketRunnableWithSyncMethod implements Runnable {
private int ticket = 10; // 共享的剩余票数
// 同步方法:等价于 synchronized(this) 包裹方法体
public synchronized void sellTicket() {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()
+ " 卖出1张票,剩余:" + (--ticket));
}
}
@Override
public void run() {
while (ticket > 0) {
sellTicket();
try {
Thread.sleep(10); // 模拟操作耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// 测试同步代码块
System.out.println("===== 测试同步代码块 =====");
TicketRunnableWithSyncBlock runnable1 = new TicketRunnableWithSyncBlock();
new Thread(runnable1, "窗口1").start();
new Thread(runnable1, "窗口2").start();
new Thread(runnable1, "窗口3").start();
// 等待上一个测试结束(仅为演示效果,实际开发不建议)
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
// 测试同步方法
System.out.println("\n===== 测试同步方法 =====");
TicketRunnableWithSyncMethod runnable2 = new TicketRunnableWithSyncMethod();
new Thread(runnable2, "窗口A").start();
new Thread(runnable2, "窗口B").start();
new Thread(runnable2, "窗口C").start();
}
}
生产者和消费者
package com.example.demo1;
import java.util.LinkedList;
// 共享缓冲区(核心同步对象)
class Buffer {
private final LinkedList<Integer> queue = new LinkedList<>();
private final int capacity = 5; // 缓冲区最大容量
// 生产者放入产品
public synchronized void put(int product) throws InterruptedException {
// 循环检查缓冲区是否已满(防止虚假唤醒)
while (queue.size() == capacity) {
System.out.println("缓冲区已满,生产者等待...");
wait(); // 释放锁并等待
}
queue.add(product);
System.out.println("生产者生产:" + product + ",当前缓冲区数量:" + queue.size());
notifyAll(); // 唤醒等待的消费者
}
// 消费者取出产品
public synchronized int take() throws InterruptedException {
// 循环检查缓冲区是否为空(防止虚假唤醒)
while (queue.isEmpty()) {
System.out.println("缓冲区为空,消费者等待...");
wait(); // 释放锁并等待
}
int product = queue.removeFirst();
System.out.println("消费者消费:" + product + ",当前缓冲区数量:" + queue.size());
notifyAll(); // 唤醒等待的生产者
return product;
}
}
// 生产者线程
class Producer implements Runnable {
private final Buffer buffer;
private int productId = 1; // 产品编号
public Producer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) { // 生产10个产品
buffer.put(productId++);
Thread.sleep(300); // 模拟生产耗时
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 消费者线程
class Consumer implements Runnable {
private final Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) { // 消费10个产品
buffer.take();
Thread.sleep(500); // 模拟消费耗时
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ProducerConsumerDemo {
public static void main(String[] args) {
Buffer buffer = new Buffer();
// 启动生产者和消费者线程
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
}
}