1、线程创建
线程的创建有多种方法,接下来我们开始逐个介绍
(1),
class Mythread extends Thread {
@Override
public void run() {
System.out.println("hello thread");
}
}
public class csdn {
public static void main(String[] args) {
Mythread mythread = new Mythread();
mythread.start();
}
}
(2),
class Myrunnable implements Runnable{
@Override
public void run() {
System.out.println("hello MyRunnable");
}
}
public class csdn {
public static void main(String[] args) {
Myrunnable myrunnable = new Myrunnable();
Thread thread = new Thread(myrunnable);
}
}
(3),
public class csdn {
public static void main(String[] args) {
Thread thread = new Thread(() ->{
System.out.println("hello thread");
});
thread.start();
}
}
(4),
public class csdn {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello Runnable");
}
});
thread.start();
}
}
线程中断
线程中断见名知意就是中断线程这里需要用的interrupt()方法:
public class demo11 {
public static void main(String[] args) {
Thread thread = new Thread(()->{
Thread thread1 = Thread.currentThread();
while(!thread1.isInterrupted()){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("hello thread");
}
});
thread.start();
thread.interrupt();
System.out.println("hello main");
}
}
这例就是在运行一次后就将线程进行中断,线程结束。
线程等待
对于线程等待我们使用join()方法来进行实现,等待就是让其他线程等待这个线程或者是让这个线程被等待,主线程可以等待子线承,子线承也可以等待子线程,总的来说就是线程之间可以相互等待,有句话叫存在即合理,下面我们来介绍为什么要有线程等待和线程等待的使用场景,
我们知到线程之间是并发进行的并且线程是“随机调度,抢占式执行”,因此可能会出现一个线程正在执行还未结束时,另一个线程开始进行会出现重叠问题。
public class demo2 {
private static int count = 0;
public static void main(String[] args) {
Thread thread1 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
Thread thread2 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
thread1.start();
thread2.start();
}
}
大家来猜一下执行结果是什么? 并且为什么会形成这种结果?就是因为线程是并发执行的,所以在一个线程可能在还未执行完的过程中另一个线程就开始执行导致结果的重叠(不一定相等)。它的结果是一个随机数。
要想解决这个问题就需要用到线程等待了,使用规则为在哪一个线程中使用另一个线程调用join()方法那么要想执行这个线程就必须等待下一个线程运行结束才能执行。
public static void main1(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
Thread thread2 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
String s = "fdsaf dsafasd";
thread1.start();
thread2.start();
thread1.join();
thread2.join();;
System.out.println(count);
}
在这里我们在主线程中使用了thread1和thread2的join()方法但是这种写法还是随机的,与上一个例代码结果都是随机值 ,正确的写法应为:
public static void main1(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
Thread thread2 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
String s = "fdsaf dsafasd";
thread1.start();
thread1.join();
thread2.start();
thread2.join();;
System.out.println(count);
}
这种写法才是真正的在主线程中子线程thread1和thread2逐个执行结果是正确的100000。我们当然也可以在子线程中等待其他线程例:
public static void main1(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()->{
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
Thread thread2 = new Thread(()->{
try {
thread1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for(int i=0;i<50000;i++){
count++;
}
System.out.println(count);
});
String s = "fdsaf dsafasd";
thread1.start();
thread2.start();
System.out.println(count);
}
这种也就是在thread2中必须先执行完thread1才能执行thread2中的内容。线程等待不必死板记忆,可灵活运用。
线程休眠
线程休眠就十分容易理解和使用了例:
Thread thread = new Thread(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
这就是一个线程休眠的使用,需要注意的是在java中线程休眠期间 线程休眠会释放它所持有的CPU和读写资源,但是线程所占用的内存资源并不会被释放。这意味着其他线程可以在休眠期间访问共享的资源,但是无法使用线程在休眠期间分配的内存。