您好,登录后才能下订单哦!
在Java中,线程的创建主要有两种方式:
- 继承Thread类:通过继承Thread
类并重写run()
方法来创建线程。
- 实现Runnable接口:通过实现Runnable
接口并将其传递给Thread
类的构造函数来创建线程。
// 继承Thread类
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running");
}
}
// 实现Runnable接口
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.start();
Thread thread2 = new Thread(new MyRunnable());
thread2.start();
}
}
线程的生命周期包括以下几个状态:
- 新建(New):线程被创建但尚未启动。
- 就绪(Runnable):线程已经启动,等待CPU调度执行。
- 运行(Running):线程正在执行run()
方法中的代码。
- 阻塞(Blocked):线程因为某些原因(如等待锁、I/O操作等)暂时停止执行。
- 终止(Terminated):线程执行完毕或因异常退出。
线程的优先级可以通过setPriority(int priority)
方法来设置,优先级范围是1(最低)到10(最高)。默认优先级为5。
Thread thread = new Thread(() -> System.out.println("Thread running"));
thread.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级
thread.start();
在多线程环境下,多个线程可能会同时访问共享资源,导致数据不一致的问题。可以通过synchronized
关键字来修饰方法或代码块,确保同一时间只有一个线程执行该代码。
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
synchronized
关键字也可以用于代码块,指定锁对象。
class Counter {
private int count = 0;
private final Object lock = new Object();
public void increment() {
synchronized (lock) {
count++;
}
}
public int getCount() {
return count;
}
}
Java提供了java.util.concurrent.locks
包中的ReentrantLock
类,可以实现更灵活的锁机制。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Counter {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
}
wait()
和notify()
方法用于线程间的通信。wait()
使当前线程进入等待状态,直到其他线程调用notify()
或notifyAll()
方法唤醒它。
class SharedResource {
private boolean flag = false;
public synchronized void produce() {
while (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
System.out.println("Produced");
notify();
}
public synchronized void consume() {
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = false;
System.out.println("Consumed");
notify();
}
}
Condition
接口提供了更灵活的线程等待和唤醒机制,通常与ReentrantLock
一起使用。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class SharedResource {
private boolean flag = false;
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void produce() {
lock.lock();
try {
while (flag) {
condition.await();
}
flag = true;
System.out.println("Produced");
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void consume() {
lock.lock();
try {
while (!flag) {
condition.await();
}
flag = false;
System.out.println("Consumed");
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
Java提供了Executor
框架来管理线程池,常用的线程池类型有:
- FixedThreadPool:固定大小的线程池。
- CachedThreadPool:根据需要创建新线程的线程池。
- ScheduledThreadPool:支持定时及周期性任务执行的线程池。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable task = new Task(i);
executor.execute(task);
}
executor.shutdown();
}
}
class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
public void run() {
System.out.println("Task " + taskId + " is running");
}
}
Callable
接口与Runnable
类似,但它可以返回结果并抛出异常。Future
表示异步计算的结果。
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<Integer> future = executor.submit(new CallableTask());
System.out.println("Future result: " + future.get());
executor.shutdown();
}
}
class CallableTask implements Callable<Integer> {
public Integer call() throws Exception {
return 42;
}
}
ConcurrentHashMap
是线程安全的哈希表,支持高并发的读写操作。
import java.util.concurrent.ConcurrentHashMap;
public class Main {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key1", 1);
map.put("key2", 2);
System.out.println(map.get("key1"));
}
}
CopyOnWriteArrayList
是线程安全的列表,适用于读多写少的场景。
import java.util.concurrent.CopyOnWriteArrayList;
public class Main {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("item1");
list.add("item2");
for (String item : list) {
System.out.println(item);
}
}
}
AtomicInteger
提供了原子操作的整数类,适用于多线程环境下的计数器。
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger atomicInt = new AtomicInteger(0);
atomicInt.incrementAndGet();
System.out.println(atomicInt.get());
}
}
AtomicReference
提供了原子操作的引用类型。
import java.util.concurrent.atomic.AtomicReference;
public class Main {
public static void main(String[] args) {
AtomicReference<String> atomicRef = new AtomicReference<>("initial");
atomicRef.set("updated");
System.out.println(atomicRef.get());
}
}
CountDownLatch
用于等待一组线程完成后再继续执行。
import java.util.concurrent.CountDownLatch;
public class Main {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Thread running");
latch.countDown();
}).start();
}
latch.await();
System.out.println("All threads finished");
}
}
CyclicBarrier
用于让一组线程相互等待,直到所有线程都到达某个屏障点。
import java.util.concurrent.CyclicBarrier;
public class Main {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All threads reached barrier"));
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println("Thread waiting at barrier");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
Semaphore
用于控制同时访问某个资源的线程数量。
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println("Thread acquired semaphore");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println("Thread released semaphore");
}
}).start();
}
}
}
死锁是指两个或多个线程互相持有对方所需的资源,导致所有线程都无法继续执行。避免死锁的方法包括: - 按顺序获取锁:确保所有线程以相同的顺序获取锁。 - 使用超时机制:在获取锁时设置超时时间,避免无限等待。
尽量减少锁的持有时间和范围,避免长时间持有锁导致其他线程无法执行。
不可变对象是线程安全的,因为它们的状态在创建后不能被修改。使用不可变对象可以减少同步的需求。
在多线程环境下,优先使用线程安全的集合类,如ConcurrentHashMap
、CopyOnWriteArrayList
等。
Java并发编程涉及的知识点非常广泛,包括线程的创建与生命周期、线程同步、线程间通信、线程池、并发集合、原子操作、并发工具类等。掌握这些知识点并遵循最佳实践,可以帮助开发者编写高效、安全的并发程序。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。