线程的创建与基本方法的使用
程序员文章站
2022-07-10 19:10:44
线程的创建方式一 :继承Threadpublic class ThreadTest extends Thread{ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("Thread:"+i); } } public static void main(String[] args) throws Int...
线程的创建
方式一 :继承Thread
public class ThreadTest extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread:"+i);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
threadTest.start();
for (int i = 0; i < 10; i++) {
System.out.println("main:"+i);
//TimeUnit.SECONDS.sleep(1);
}
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49985:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\idea_workplace\javaBase\target\classes"
main:0
main:1
main:2
thread:1
main:3
thread:2
main:4
main:5
main:6
main:7
main:8
main:9
main:10
。。。。
方式二:实现Runnable接口
public class RunnerbleTest {
public static void main(String[] args) {
new Thread(new A(),"A").start();
new Thread(new A(),"B").start();
}
static class A implements Runnable{
@Override
public void run() {
int i = 5;
while (i-->=0){
System.out.println(Thread.currentThread().getName()+"==="+Thread.currentThread().getState());
}
}
}
}
B===RUNNABLE
A===RUNNABLE
A===RUNNABLE
A===RUNNABLE
A===RUNNABLE
B===RUNNABLE
B===RUNNABLE
B===RUNNABLE
A===RUNNABLE
B===RUNNABLE
A===RUNNABLE
B===RUNNABLE
方式三:实现Callble接口
public class CallableTest implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 1023;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableTest test = new CallableTest();
FutureTask futureTask = new FutureTask<>(test);
Thread thread = new Thread(futureTask, "A");
thread.start();
Object o = futureTask.get();
System.out.println(o);
}
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=64112:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA "
1023
Callble创建线程有点绕,我画了一个图(基于源码和API)供大家参考理解,首先我们知道Thread是实现了Runnble接口的,FutureTask也是实现了Runnable接口,而FutureTask依赖Callabe,通过了这种间接的方式创建了线程
public class Thread implements Runnable {
......
}
这里是通过构造器传入Callable
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
方式四:通过自定义线程池
public class ThreadPoolExecutorDemo {
public static void main(String[] args) {
//自定义线程池,阿里开发手册推荐
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,//核心线程数,就是默认开启线程数
Runtime.getRuntime().availableProcessors(),//最大线程数
3,//超时时间
TimeUnit.SECONDS,//超时单位
new ArrayBlockingQueue<>(3),//阻塞队列
Executors.defaultThreadFactory(),//线程工厂
new ThreadPoolExecutor.CallerRunsPolicy()//执行策略
);
for (int i = 0; i < 9 ; i++) {
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
//关闭线程池
threadPoolExecutor.shutdown();
}
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=50720:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;E:\idea_workplace\javaBase\target\classes"
pool-1-thread-1
main
pool-1-thread-2
pool-1-thread-4
pool-1-thread-1
main
pool-1-thread-4
pool-1-thread-3
pool-1-thread-2
Process finished with exit code 0
基本方法使用
join()方法
join():强制性加入,并且还要把自己的线程执行完毕后才给其他线程机会
public class ThreadTest extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread:"+i);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
threadTest.start();
for (int i = 0; i < 10; i++) {
if (i == 5){
threadTest.join();//另外一个线程任务强行加入,执行完毕才继续向下
}
System.out.println("main:"+i);
//TimeUnit.SECONDS.sleep(1);
}
}
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=65360:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA
main:0
main:1
main:2
main:3
main:4
Thread:0
Thread:1
Thread:2
Thread:3
Thread:4
Thread:5
Thread:6
Thread:7
Thread:8
Thread:9
main:5
main:6
main:7
main:8
main:9
setDaemon()
新建的线程默认不是守护线程,我们在设置为守护线程时候,必须在start之前设置.。
守护线程重点是守护,守护的对象如果不在了,他也会跟着消亡
public class ThreadTest extends Thread{
@Override
public void run() {
while (true){
System.out.println(520);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
boolean daemon = threadTest.isDaemon();//
threadTest.setDaemon(true);//
threadTest.start();
for (int i = 0; i < 5; i++) {
System.out.println("main:"+i);
}
}
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49270:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program
main:0
main:1
main:2
main:3
main:4
Process finished with exit code 0
还有一种情况
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49270:F:\MyDir\IDEA\IDEA2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program
main:0
main:1
main:2
main:3
main:4
520
520
不是说守护的线程结束了,它也会跟着消亡吗,怎么还运行呢?
这是因为死亡也是需要时间的啊,在这段时间内,它可以做自己的事情。上面那种情况是你死了,我也立刻死。所以才看到只有主线程打印
yield() :谦让
调用本方法时,当前线程谦让一下,让另一个线程执行,但是,另一个线程不一定执行,万一它害羞呢
推荐阅读