📅  最后修改于: 2023-12-03 14:42:20.277000             🧑  作者: Mango
Java 是一种非常流行的面向对象编程语言,它支持多线程编程。在计算机中,多线程是指一个程序同时执行多个线程,每个线程都可以独立执行不同的任务。Java 通过 Thread
类来支持多线程编程。本文将为你介绍 Java 多线程编程的相关知识。
Java 中创建线程有两种方法:
Thread
类Runnable
接口Thread
类继承 Thread
类并重写 run
方法,然后创建该类的对象并调用 start
方法即可创建线程。示例代码如下:
class MyThread extends Thread {
public void run() {
System.out.println("Hello, world!");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
输出:
Hello, world!
Runnable
接口实现 Runnable
接口并重写 run
方法,然后创建该类的对象并作为参数传递给 Thread
类的构造方法,最后调用 start
方法即可创建线程。示例代码如下:
class MyRunnable implements Runnable {
public void run() {
System.out.println("Hello, world!");
}
}
public class Main {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
}
}
输出:
Hello, world!
当多个线程共享同一个资源时,就会发生线程同步问题。Java 提供了多种方式来解决线程同步问题:
synchronized
方法synchronized
代码块volatile
关键字Lock
接口synchronized
方法将需要同步的方法前加上 synchronized
关键字,可以实现线程同步,使得多个线程无法同时访问该方法。示例代码如下:
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized void decrement() {
count--;
}
public synchronized int getCount() {
return count;
}
}
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.decrement();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(counter.getCount());
}
}
输出:
0
synchronized
代码块使用 synchronized
关键字将需要同步的代码块包裹起来,也可以实现线程同步。示例代码如下:
class Counter {
private int count = 0;
public void increment() {
synchronized (this) {
count++;
}
}
public void decrement() {
synchronized (this) {
count--;
}
}
public int getCount() {
return count;
}
}
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.decrement();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(counter.getCount());
}
}
输出:
0
volatile
关键字volatile
关键字可以实现线程之间的可见性,即一个线程修改了共享变量的值,其他线程能够立即看到该变化。示例代码如下:
class Counter {
private volatile int count = 0;
public void increment() {
count++;
}
public void decrement() {
count--;
}
public int getCount() {
return count;
}
}
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.decrement();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(counter.getCount());
}
}
输出:
0
Lock
接口Lock
接口提供了更加灵活的锁定机制,可以实现更细粒度的线程同步。与 synchronized
不同,Lock
接口需要程序员手动释放锁定。示例代码如下:
class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public void decrement() {
lock.lock();
try {
count--;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
}
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter.decrement();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(counter.getCount());
}
}
输出:
0
线程池是一种提高线程利用率、减少创建线程的开销的技术。Java 中通过 ThreadPoolExecutor
类来实现线程池。示例代码如下:
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executorService.submit(new Task(i));
}
executorService.shutdown();
}
}
class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("Task #" + taskId + " is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task #" + taskId + " is completed.");
}
}
输出:
Task #0 is running.
Task #1 is running.
Task #2 is running.
Task #3 is running.
Task #4 is running.
Task #5 is running.
Task #6 is running.
Task #7 is running.
Task #8 is running.
Task #9 is running.
Task #10 is running.
Task #11 is running.
Task #12 is running.
Task #13 is running.
Task #14 is running.
Task #15 is running.
Task #16 is running.
Task #17 is running.
Task #18 is running.
Task #19 is running.
Task #20 is running.
Task #21 is running.
Task #22 is running.
Task #23 is running.
Task #24 is running.
Task #25 is running.
Task #26 is running.
Task #27 is running.
Task #28 is running.
Task #29 is running.
Task #30 is running.
Task #31 is running.
Task #32 is running.
Task #33 is running.
Task #34 is running.
Task #35 is running.
Task #36 is running.
Task #37 is running.
Task #38 is running.
Task #39 is running.
Task #40 is running.
Task #41 is running.
Task #42 is running.
Task #43 is running.
Task #44 is running.
Task #45 is running.
Task #46 is running.
Task #47 is running.
Task #48 is running.
Task #49 is running.
Task #50 is running.
Task #51 is running.
Task #52 is running.
Task #53 is running.
Task #54 is running.
Task #55 is running.
Task #56 is running.
Task #57 is running.
Task #58 is running.
Task #59 is running.
Task #60 is running.
Task #61 is running.
Task #62 is running.
Task #63 is running.
Task #64 is running.
Task #65 is running.
Task #66 is running.
Task #67 is running.
Task #68 is running.
Task #69 is running.
Task #70 is running.
Task #71 is running.
Task #72 is running.
Task #73 is running.
Task #74 is running.
Task #75 is running.
Task #76 is running.
Task #77 is running.
Task #78 is running.
Task #79 is running.
Task #80 is running.
Task #81 is running.
Task #82 is running.
Task #83 is running.
Task #84 is running.
Task #85 is running.
Task #86 is running.
Task #87 is running.
Task #88 is running.
Task #89 is running.
Task #90 is running.
Task #91 is running.
Task #92 is running.
Task #93 is running.
Task #94 is running.
Task #95 is running.
Task #96 is running.
Task #97 is running.
Task #98 is running.
Task #99 is running.
Task #1 is completed.
Task #2 is completed.
Task #0 is completed.
Task #7 is completed.
Task #6 is completed.
Task #9 is completed.
Task #5 is completed.
Task #4 is completed.
Task #3 is completed.
Task #8 is completed.
Task #11 is completed.
Task #12 is completed.
Task #13 is completed.
Task #14 is completed.
Task #15 is completed.
Task #16 is completed.
Task #17 is completed.
Task #18 is completed.
Task #19 is completed.
Task #20 is completed.
Task #21 is completed.
Task #22 is completed.
Task #23 is completed.
Task #24 is completed.
Task #25 is completed.
Task #26 is completed.
Task #27 is completed.
Task #28 is completed.
Task #29 is completed.
Task #30 is completed.
Task #31 is completed.
Task #32 is completed.
Task #33 is completed.
Task #34 is completed.
Task #35 is completed.
Task #36 is completed.
Task #37 is completed.
Task #38 is completed.
Task #39 is completed.
Task #40 is completed.
Task #41 is completed.
Task #42 is completed.
Task #43 is completed.
Task #44 is completed.
Task #45 is completed.
Task #46 is completed.
Task #47 is completed.
Task #48 is completed.
Task #49 is completed.
Task #50 is completed.
Task #51 is completed.
Task #52 is completed.
Task #53 is completed.
Task #54 is completed.
Task #55 is completed.
Task #56 is completed.
Task #57 is completed.
Task #58 is completed.
Task #59 is completed.
Task #60 is completed.
Task #61 is completed.
Task #62 is completed.
Task #63 is completed.
Task #64 is completed.
Task #65 is completed.
Task #66 is completed.
Task #67 is completed.
Task #68 is completed.
Task #69 is completed.
Task #70 is completed.
Task #71 is completed.
Task #72 is completed.
Task #73 is completed.
Task #74 is completed.
Task #75 is completed.
Task #76 is completed.
Task #77 is completed.
Task #78 is completed.
Task #79 is completed.
Task #80 is completed.
Task #81 is completed.
Task #82 is completed.
Task #83 is completed.
Task #84 is completed.
Task #85 is completed.
Task #86 is completed.
Task #87 is completed.
Task #88 is completed.
Task #89 is completed.
Task #90 is completed.
Task #91 is completed.
Task #92 is completed.
Task #93 is completed.
Task #94 is completed.
Task #95 is completed.
Task #96 is completed.
Task #97 is completed.
Task #98 is completed.
Task #99 is completed.
本文介绍了 Java 多线程编程的相关知识,包括创建线程、线程同步和线程池。Java 多线程编程是 Java 程序员的必备技能,希望本文能够对你有所帮助。