文章目录
三种创建线程的方法继承Thread类(没有返回值)实现Runable接口(没有返回值)实现Callable接口(有返回值)
CountDownLatch
三种创建线程的方法
利用多线程去计算加法,主要有三步
分解任务为子任务新建线程执行子任务(如何得到结果或保存结果)得到子任务的结果,合并得到最终结果
创建线程主要有三种方法,前两种没有返回值,callable接口有返回值。
继承Thread类(没有返回值)
public class SumThread extends Thread {
private long start
;
private long end
;
private int num
;
private long[] result
;
private CountDownLatch cdl
;
public SumThread(long start
, long end
, int num
, long[] result
, CountDownLatch cdl
) {
this.start
= start
;
this.end
= end
;
this.num
= num
;
this.result
= result
;
this.cdl
= cdl
;
}
@Override
public void run() {
long sum
= 0;
for (long i
=start
;i
<end
;i
++){
sum
+= i
;
}
result
[num
] = sum
;
cdl
.countDown();
}
}
public class SumParallelThread {
public static void main(String
[] args
) throws InterruptedException
{
int N
= 90000000;
int numThread
= 3;
parallel(N
, numThread
);
}
public static void parallel(int N
, int numThread
) throws InterruptedException
{
long[] result
= new long[numThread
];
CountDownLatch cdl
= new CountDownLatch(numThread
);
long start
= System
.currentTimeMillis();
for (int i
=0;i
<numThread
;i
++){
SumThread thread
= new SumThread(i
*N
/numThread
, (i
+1)*N
/numThread
, i
, result
, cdl
);
thread
.start();
}
cdl
.await();
long sum
= 0;
for (long r
: result
)
sum
+= r
;
long end
= System
.currentTimeMillis();
System
.out
.println("并行计算结果:"+sum
);
System
.out
.println("并行计算时间:"+(end
-start
)+"ms");
}
}
实现Runable接口(没有返回值)
public class SumThreadRunnable implements Runnable {
private long start
;
private long end
;
private long[] result
;
private CountDownLatch cdl
;
private int num
;
public SumThreadRunnable(long start
, long end
, long[] result
, CountDownLatch cdl
, int num
){
this.start
= start
;
this.end
= end
;
this.result
= result
;
this.cdl
= cdl
;
this.num
= num
;
}
@Override
public void run() {
long sum
= 0;
for (long i
=start
;i
<=end
;i
++){
sum
+= i
;
}
result
[num
] = sum
;
cdl
.countDown();
}
}
public class SumParallelRunnable {
public static void main(String
[] args
) throws InterruptedException
{
int N
= 90000000;
int numThread
= 3;
countDownLatchSum(N
, numThread
);
}
public static void countDownLatchSum(int N
, int numThread
) throws InterruptedException
{
long start
= System
.currentTimeMillis();
CountDownLatch cdl
= new CountDownLatch(numThread
);
long[] result
= new long[numThread
];
long sum
= 0;
for (int i
=0;i
<numThread
;i
++){
new Thread(new SumThreadRunnable(i
*N
/numThread
, (i
+1)*N
/numThread
, result
, cdl
, i
)).start();
}
cdl
.await();
for (long r
: result
)
sum
+= r
;
long end
= System
.currentTimeMillis();
System
.out
.println("并行计算耗时:"+(end
-start
)+"ms");
System
.out
.println("并行计算结果:"+sum
);
}
}
实现Callable接口(有返回值)
public class SumThreadCallable implements Callable<Long> {
private long start
;
private long end
;
public SumThreadCallable(long start
, long end
){
this.start
= start
;
this.end
= end
;
}
@Override
public Long
call() throws Exception
{
long sum
= 0;
for (long i
=start
;i
<end
;i
++){
sum
+= i
;
}
return sum
;
}
}
public class SumParallelCallable {
public static void main(String
[] args
) throws ExecutionException
, InterruptedException
{
int numThread
= 3;
int N
= 90000000;
parallel(N
, numThread
);
}
public static void parallel(int N
, int numThread
) throws ExecutionException
, InterruptedException
{
ExecutorService executor
= Executors
.newFixedThreadPool(numThread
);
long start1
= System
.currentTimeMillis();
List
<Future
<Long>> ans
= new ArrayList<>();
for (int i
=0;i
<numThread
;i
++){
Future
<Long> a
= executor
.submit(new SumThreadCallable(i
*N
/numThread
, (i
+1)*N
/numThread
));
ans
.add(a
);
}
long sum
= 0;
for (Future
<Long> i
: ans
){
long tmp
= i
.get();
System
.out
.println("线程"+i
+"的结果是:"+tmp
);
sum
+= tmp
;
}
long end1
= System
.currentTimeMillis();
System
.out
.println("并行计算耗时:"+(end1
-start1
)+"ms");
System
.out
.println("并行计算结果:"+sum
);
}
}
CountDownLatch
countDownLatch 像是一个计数器,线程完成一个记录一个,计数器递减,只能使用一次。 可以用来控制线程按顺序执行,主要有以下几个方法:
public CountDownLatch(int count
) {};
public void await() throws InterruptedException
{ };
public boolean await(long timeout
, TimeUnit unit
) throws InterruptedException
{ };
public void countDown() {};