线程的实现方法
通过集成java.lang.Thread线程类来创建一个线程通过实现java.lang.Runnable接口来创建一个线程带返回值的线程接口CallableJava多线程之Callable接口的实现join()加入线程,会让主线程等待sleep()线程休眠yeild()让出CPU执行权限从下面的代码例子得到结论
我自己对这个概念当时记得,长时间不用,然后又忘了,在这里做笔记给自己回顾使用
通过集成java.lang.Thread线程类来创建一个线程
package com
.jay
.Thread
;
public class TestThread {
public static void main(String
[] args
) {
System
.out
.println("主线程ID是: " + Thread
.currentThread().getId());
Thread t1
= new MyThread("线程1");
t1
.start();
Thread t2
= new MyThread("线程2");
t2
.run();
}
static class MyThread extends Thread {
private String name
;
public MyThread(String name
) {
this.name
= name
;
}
@Override
public void run() {
System
.out
.println("名称:" + name
+ "的线程ID是:" + Thread
.currentThread().getId());
}
}
}
通过实现java.lang.Runnable接口来创建一个线程
package com
.jay
.Thread
;
public class TestRunnable {
public static void main(String
[] args
) {
System
.out
.println("主线程的ID是: " + Thread
.currentThread().getId());
MyRunnable r1
= new MyRunnable("线程1");
Thread t1
= new Thread(r1
);
t1
.start();
MyRunnable r2
= new MyRunnable("线程2");
Thread t2
= new Thread(r2
);
t2
.run();
}
static class MyRunnable implements Runnable{
private String name
;
public MyRunnable(String name
) {
this.name
= name
;
}
@Override
public void run() {
System
.out
.println("名字:" + name
+ "的线程ID是: " + Thread
.currentThread().getId());
}
}
}
带返回值的线程接口Callable
package com
.jay
.Thread
;
import java
.util
.concurrent
.*;
public class TestCallable {
public static void main(String
[] args
) {
ExecutorService threadPool
= Executors
.newFixedThreadPool(3);
MyCallable c1
= new MyCallable("线程1");
MyCallable c2
= new MyCallable("线程2");
MyCallable c3
= new MyCallable("线程3");
Future f1
= threadPool
.submit(c1
);
Future f2
= threadPool
.submit(c2
);
Future f3
= threadPool
.submit(c3
);
try {
System
.out
.println(f1
.get().toString());
System
.out
.println(f2
.get().toString());
System
.out
.println(f3
.get().toString());
} catch (InterruptedException e
) {
e
.printStackTrace();
} catch (ExecutionException e
) {
e
.printStackTrace();
}finally {
threadPool
.shutdown();
}
}
static class MyCallable implements Callable {
private String name
;
public MyCallable(String name
) {
this.name
= name
;
}
@Override
public Object
call() throws Exception
{
return name
+ "返回了东西...";
}
}
}
Java多线程之Callable接口的实现
package com
.jay
.Thread
;
import java
.util
.concurrent
.Callable
;
import java
.util
.concurrent
.ExecutionException
;
import java
.util
.concurrent
.FutureTask
;
public class TestCallableTwo {
public static void main(String
[] args
) {
ThreadDemo td
= new ThreadDemo();
FutureTask
<Integer
> result
= new FutureTask<>(td
);
new Thread(result
).start();
try {
Integer sum
= result
.get();
System
.out
.println(sum
);
System
.out
.println("------------------------------------");
} catch (InterruptedException | ExecutionException e
) {
e
.printStackTrace();
}
}
static class ThreadDemo implements Callable<Integer
> {
@Override
public Integer
call() throws Exception
{
int sum
= 0;
for (int i
= 0; i
<= 100000; i
++) {
sum
+= i
;
}
return sum
;
}
}
}
join()加入线程,会让主线程等待
package com
.jay
.Thread
;
public class TestJoin {
public static void main(String
[] args
) throws InterruptedException
{
Thread t1
= new MyJoinThread("线程1");
t1
.start();
t1
.join();
for (int i
= 0; i
< 10; i
++){
if(i
== 5){
Thread t2
= new MyJoinThread("线程2");
t2
.start();
t2
.join();
}
System
.out
.println("main主线程: " + Thread
.currentThread().getName() + " ====> " + i
);
}
}
static class MyJoinThread extends Thread{
public MyJoinThread(String name
) {
super(name
);
}
@Override
public void run() {
for (int i
= 0; i
< 5; i
++){
System
.out
.println("当前线程: " + Thread
.currentThread().getName() + " ===> " + i
);
}
}
}
}
sleep()线程休眠
package com
.jay
.Thread
;
public class TestSleep {
private int i
= 10;
private Object object
= new Object();
public static void main(String
[] args
) {
TestSleep testSleep
= new TestSleep();
Thread t1
= testSleep
.new MyTestThread();
t1
.start();
Thread t2
= testSleep
.new MyTestThread();
t2
.start();
}
class MyTestThread extends Thread{
@Override
public void run() {
synchronized (object
){
i
++;
System
.out
.println("线程: " + Thread
.currentThread().getName() + "开始执行,i的值为:" + i
);
System
.out
.println("线程: " + Thread
.currentThread().getName() + "准备进入休眠状态...");
try {
Thread
.sleep(1000);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
System
.out
.println("线程: " + Thread
.currentThread().getName() + "休眠结束...");
i
++;
System
.out
.println("线程: " + Thread
.currentThread().getName() + "继续执行,i的值为===========>:" + i
);
}
}
}
}
yeild()让出CPU执行权限
package com
.jay
.Thread
;
public class TestYield {
public static void main(String
[] args
) {
MyYieldThread t
= new MyYieldThread("线程1");
t
.start();
MyYieldThread2 t2
= new MyYieldThread2("线程2");
t2
.start();
System
.out
.println("主线程名称:"+Thread
.currentThread().getName());
}
static class MyYieldThread extends Thread{
private String name
;
public MyYieldThread(String name
) {
this.name
= name
;
}
@Override
public void run() {
System
.out
.println("名字: " + name
+ "执行");
long start
= System
.currentTimeMillis();
int count
= 0;
for (int i
= 0; i
< 1000000; i
++){
count
= count
+ (i
+ 1);
Thread
.yield();
}
long end
= System
.currentTimeMillis();
System
.out
.println(name
+ "结果count: " + count
+ ",计算耗时: " + (end
- start
) + "毫秒");
}
}
static class MyYieldThread2 extends Thread{
private String name
;
public MyYieldThread2(String name
) {
this.name
= name
;
}
@Override
public void run() {
System
.out
.println("名字: " + name
+ "执行");
long start
= System
.currentTimeMillis();
int num
= 0;
for (int i
= 0; i
< 10000000; i
++){
num
+= i
* 8;
}
long end
= System
.currentTimeMillis();
System
.out
.println(name
+ "结果num: " + num
+ ",计算耗时: " + (end
- start
) + "毫秒");
}
}
}
从下面的代码例子得到结论
1、Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值。
2、通常在使用Callable的时候,也会涉及到Future,一般配合一起使用,一个产生结果,一个拿到结果。
3、假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到最终计算结果
参考:https://www.jianshu.com/p/94c1c34053d0