Java 多线程-----基础篇
1 线程和进程的区别
- 进程:是操作系统进行资源分配和调度的基本单位,每个进程拥有独立的内存空间、文件描述符、寄存器等资源
- 线程:是进程内的一个执行单元,是CPU调度的基本单位。线程共享进程的资源
2 多线程实现方式
2.1 继承Thread
下面是一个简单的例子 ,通过运行结果我们可以看到两个任务是并行的。
public class Demo1 {
public static void main(String [] args){
Demo1 demo1 = new Demo1();
demo1.fun1();
}
public void fun1(){
ThreadDemo threadDemo1 = new ThreadDemo();
ThreadDemo threadDemo2 = new ThreadDemo();
threadDemo1.start();
threadDemo2.start();
}
class ThreadDemo extends Thread{
private int count = 0;
public ThreadDemo(){
}
public void run(){
for(int i = 0 ;i<100;i++){
System.out.println(i);
}
}
}
}
2.2 实现Runnable类
在这里用到了Thread类的构造函数Thread(Runnable target),Runnale是一个函数式接口,函数式接口。就是里面只能有一个需要实现的接口,这意味我们可以使用Lambda表达式来简化程序
public class Demo1 {
public static void main(String [] args){
Demo1 demo1 = new Demo1();
demo1.fun1();
}
public void fun1(){
ThreadDemo threadDemo1 = new ThreadDemo();
ThreadDemo threadDemo2 = new ThreadDemo();
new Thread(threadDemo1).start();
new Thread(threadDemo2).start();
}
class ThreadDemo implements Runnable{
private int count = 0;
public ThreadDemo(){
}
public void run(){
for(int i = 0 ;i<100;i++){
System.out.println(i);
}
}
}
}
2.3 实现Callable
特点是能通过FutureTask拿到结果
/**
* Callable 例子
*/
public class CallableDemo {
public static void main(String []args){
CallableDemo callableDemo = new CallableDemo();
callableDemo.fun();
}
public void fun(){
FutureTask<String> futureTask = new FutureTask<String>(callable);
try {
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("hhhhhhs");
}
private Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "I want to be greater";
}
};
}
2.4 线程池实现
线程池主要好处就是避免线程频繁的创建和销毁,增加对系统的开销。
线程池详细介绍:https://www.cnblogs.com/minblog/p/16352356.html
public class DemoTask {
public static void main(String[] args) {
ExecutorService executorService1 = Executors.newFixedThreadPool(1);
executorService1.execute(()->{System.out.println("22222");});
}
}
3 线程的一些常用方法和状态变更
sleep(long millis) : 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
sleep(long millis, int nanos) 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)
join():等待该线程终止 ;
join( long millis) : 也是等待该线程终止,不过最大时间为millis毫秒。
yield() :让当前线程主动放弃CPU资源,进行就绪状态。
getPriority() / setPriority(int priority) 获取/设置线程优先级,优先级高的更可能被CPU调度
setDaemon(boolean on) : 设置成守护线程,当所有非守护进程结束时,守护线程会自动终止。JVM会等待所有非守护线程结束后才停止,设计的目的是为其他非守护线程提供服务
interrupt(): 向线程发送中断信号,非强制终止,可以用于优雅终止线程, 如下面代码所示,程序将在运行1s后退出,还有个作用是唤醒阻塞线程,如一些阻塞操作,sleep、join、wait都会catch这个异常,通过主动发送中断,结束阻塞
public class DemoTask {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.interrupted()) {
System.out.println(1111);
}
}
});
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
}


浙公网安备 33010602011771号