线程:可以理解为在进程中独立运行的子任务
线程创建的方式:
1.继承Thread类
package com.tony;
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Hello,Thread...");
}
}
测试:(ThreadTest.class)
package com.tony;
public class ThreadTest {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
/**
* 使用线程时 代码的运行结果与执行顺序无关
* CPU随机执行
* start()方法的顺序不代表线程启动的顺序
*/
}
}
2.实现Runnable接口
package com.tony;
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Hello,Runnable...");
}
}
测试:RunnabeTest.class
package com.tony;
public class RunnableTest {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
}
}
匿名实现线程:
package com.tony;
public class Demo {
public static void main(String[] args) {
new Thread() {
public void run() {
System.out.println("Hello,Thread...");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello,Runnable...");
}
}).start();
}
}
3.Callable接口和Future接口
package com.tony.app;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadCallable {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建Callable对象
MyCallable myCallable = new MyCallable();
// 使用FutureTask包装Callable对象
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
// 开启线程
new Thread(futureTask,"求和线程").start();
// 获取线程的返回值
Integer sum = futureTask.get(); // 一直阻塞 直到call()返回值为止
// 输出返回值
System.out.println("sum:" + sum);
System.out.println("Thead.currentThread():" + Thread.currentThread().getName());
}
}
class MyCallable implements Callable<Integer> {
private Integer sum = 0;
// 泛型指定返回值的数据类型
@Override
public Integer call() throws Exception {
for (int i = 0; i < 10; i++) {
sum += i;
}
System.out.println("Thead.currentThread():" + Thread.currentThread().getName());
return sum;
}
}
结果:
Thead.currentThread():求和线程
sum:45
Thead.currentThread():main
在使用多线程技术时 代码的运行结果与代码的执行顺序或调用顺序无关
线程是一个子任务 CPU以不确定的方式来调用线程中的run方法
如果多次调用start() 会出现 java.lang.IllegalThreadStateException异常
执行start()的顺序不代表线程启动的顺序
非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改值不同步的情况 进而影响程序的执行流程