1、简介
我们在平常开发中,经常会遇到多线程并发操作,而这部分往往是入门比较难的,我将带领大家从基础入门,逐渐深入多线程的原理,帮助大家更快更牢掌握多线程开发。
2、线程创建的方式
2.1、通过继承Thread类
具体实现如下:
public class ThreadTest {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
System.out.println("线程执行了!");
}
}
2.2、通过实现Runnable接口
具体实现如下:
public class ThreadTest {
public static void main(String[] args) {
MyThread task = new MyThread();
Thread t = new Thread(task);
t.start();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println("线程执行了!");
}
}
2.3、通过实现Callable接口
具体实现如下:
public class ThreadTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThread task = new MyThread();
// 计算1-100的和,并且获取返回值
FutureTask<Integer> ft = new FutureTask<>(task);
Thread t = new Thread(ft);
t.start();
System.out.println(ft.get());
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() {
int sum = 0;
for (int i = 0; i <= 100; i++){
sum += i;
}
return sum;
}
}
3、多线程开发案例
3.1、多线程计算数组和
多线程计算数组和,五个线程计算数组和,具体示例如下:
3.1.1、继承Thread类实现
public class ArrSumThread {
public static void main(String[] args) throws InterruptedException {
int[] arr = new int[]{1,2,3,4,5,6,7,8,9,0};
MyThread[] threads = new MyThread[5];
int step = 5;
for(int i = 0; i < arr.length / 2; i++){
threads[i] = new MyThread(i, step, arr);
threads[i].start();
threads[i].join();
}
System.out.println(MyThread.sum);
}
static class MyThread extends Thread{
static int sum = 0; // 多线程情况下,类共享
private int step;
private int index;
private int[] arr;
public void setStep(int step) {
this.step = step;
}
public void setArr(int[] arr) {
this.arr = arr;
}
public void setIndex(int index) {
this.index = index;
}
public MyThread(){}
public MyThread(int index,int step, int[] arr){
this.index = index;
this.step = step;
this.arr = arr;
}
@Override
public void run() {
for(int i = index; i < arr.length; i += step){
sum += arr[i];
}
System.out.println(getName() + "计算结果为: " + sum);
}
}
}
3.1.2、实现Runnable接口
public class ArrSumThread1 {
public static void main(String[] args) throws InterruptedException {
int[] arr = new int[]{1,2,3,4,5,6,7,8,9,0};
MyThread[] threads = new MyThread[5];
int step = 5;
for(int i = 0; i < arr.length / 2; i++){
threads[i] = new MyThread(i, step, arr);
Thread t = new Thread(threads[i]);
t.start();
t.join();
}
System.out.println(MyThread.sum);
}
static class MyThread implements Runnable{
static int sum = 0;
private int step;
private int index;
private int[] arr;
public void setStep(int step) {
this.step = step;
}
public void setArr(int[] arr) {
this.arr = arr;
}
public void setIndex(int index) {
this.index = index;
}
public MyThread(){}
public MyThread(int index,int step, int[] arr){
this.index = index;
this.step = step;
this.arr = arr;
}
@Override
public void run() {
for(int i = index; i < arr.length; i += step){
sum += arr[i];
}
System.out.println(Thread.currentThread().getName() + "计算结果为: " + sum);
}
}
}
3.1.3、实现Callable接口
public class ArrSumThread1 {
public static void main(String[] args) throws Exception {
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
MyThread[] threads = new MyThread[5];
int step = 5;
int sum = 0;
for (int i = 0; i < arr.length / 2; i++) {
threads[i] = new MyThread(i, step, arr);
FutureTask<Integer> task = new FutureTask<Integer>(threads[i]);
Thread t = new Thread(task);
t.start();
sum += task.get();
}
System.out.println(sum);
}
static class MyThread implements Callable<Integer> {
int sum = 0;
private int step;
private int index;
private int[] arr;
public int getSum() {
return sum;
}
public void setStep(int step) {
this.step = step;
}
public void setArr(int[] arr) {
this.arr = arr;
}
public void setIndex(int index) {
this.index = index;
}
public MyThread() {
}
public MyThread(int index, int step, int[] arr) {
this.index = index;
this.step = step;
this.arr = arr;
}
@Override
public Integer call() {
for (int i = index; i < arr.length; i += step) {
sum += arr[i];
}
System.out.println(Thread.currentThread().getName() + "计算结果为: " + sum);
return sum;
}
}
}
3.2、多线程抢红包
五个人抢三个红包案例,红包总额100,最少0.01元,具体实现如下:
public class TestMian {
public static void main(String[] args) {
MyThread task = new MyThread();
// 五个人抢三个红包案例
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
Thread t3 = new Thread(task);
Thread t4 = new Thread(task);
Thread t5 = new Thread(task);
t1.setName("aa");
t2.setName("bb");
t3.setName("cc");
t4.setName("dd");
t5.setName("ee");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class MyThread implements Runnable{
int count = 3;
public static final double MIN = 0.01;
double total = 100;
@Override
public void run() {
synchronized (MyThread.class){
// 如果count 为0,表示红包抢完了
if(count == 0){
System.out.println(Thread.currentThread().getName() + "红包抢完了!");
}else{
double prize = 0;
// 要保证每个红包最少0.01
double bound = total - (count - 1) * MIN;
if(count == 1){
// 最后一个红包是剩余金额
prize = total;
}else {
Random random = new Random();
prize = random.nextDouble(bound);
if (prize < MIN){
prize = MIN;
}
}
System.out.println(Thread.currentThread().getName() + "抢到了:" + prize + " 钱红包!");
total -= prize;
count--;
}
}
}
}
4、总结
多线程对于开发人员来说是难以掌握和精通的,只有不断练习,培养并发编程意识,才能更更好利用多线程进行开发。
本人是一个从小白自学计算机技术,对前端、运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:it自学社团。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)