Java线程学习之并发编程知识点有哪些

发布时间:2022-06-22 13:35:10 作者:iii
来源:亿速云 阅读:160

Java线程学习之并发编程知识点有哪些

1. 线程基础

1.1 线程的创建

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

1.2 线程的生命周期

线程的生命周期包括以下几个状态: - 新建(New):线程被创建但尚未启动。 - 就绪(Runnable):线程已经启动,等待CPU调度执行。 - 运行(Running):线程正在执行run()方法中的代码。 - 阻塞(Blocked):线程因为某些原因(如等待锁、I/O操作等)暂时停止执行。 - 终止(Terminated):线程执行完毕或因异常退出。

1.3 线程的优先级

线程的优先级可以通过setPriority(int priority)方法来设置,优先级范围是1(最低)到10(最高)。默认优先级为5。

Thread thread = new Thread(() -> System.out.println("Thread running"));
thread.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级
thread.start();

2. 线程同步

2.1 同步方法

在多线程环境下,多个线程可能会同时访问共享资源,导致数据不一致的问题。可以通过synchronized关键字来修饰方法或代码块,确保同一时间只有一个线程执行该代码。

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

2.2 同步代码块

synchronized关键字也可以用于代码块,指定锁对象。

class Counter {
    private int count = 0;
    private final Object lock = new Object();

    public void increment() {
        synchronized (lock) {
            count++;
        }
    }

    public int getCount() {
        return count;
    }
}

2.3 锁机制

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

3. 线程间通信

3.1 wait() 和 notify()

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

3.2 Condition

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

4. 线程池

4.1 Executor框架

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

4.2 Future和Callable

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

5. 并发集合

5.1 ConcurrentHashMap

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

5.2 CopyOnWriteArrayList

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

6. 原子操作

6.1 AtomicInteger

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

6.2 AtomicReference

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

7. 并发工具类

7.1 CountDownLatch

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

7.2 CyclicBarrier

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

7.3 Semaphore

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

8. 并发编程的最佳实践

8.1 避免死锁

死锁是指两个或多个线程互相持有对方所需的资源,导致所有线程都无法继续执行。避免死锁的方法包括: - 按顺序获取锁:确保所有线程以相同的顺序获取锁。 - 使用超时机制:在获取锁时设置超时时间,避免无限等待。

8.2 减少锁的粒度

尽量减少锁的持有时间和范围,避免长时间持有锁导致其他线程无法执行。

8.3 使用不可变对象

不可变对象是线程安全的,因为它们的状态在创建后不能被修改。使用不可变对象可以减少同步的需求。

8.4 使用线程安全的集合

在多线程环境下,优先使用线程安全的集合类,如ConcurrentHashMapCopyOnWriteArrayList等。

9. 总结

Java并发编程涉及的知识点非常广泛,包括线程的创建与生命周期、线程同步、线程间通信、线程池、并发集合、原子操作、并发工具类等。掌握这些知识点并遵循最佳实践,可以帮助开发者编写高效、安全的并发程序。

推荐阅读:
  1. jquery学习之重要知识点
  2. Java基础学习之-多线程学习知识点的学习

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:bootstrap是不是国内开发的

下一篇:TypeScript中的类型断言语法怎么使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》