并发编程线程基础

进程与线程

进程是系统分配资源的基本单位,线程是进程的一个执行路径,一个进程可以有多个线程,线程之间共享进程的资源
在这里插入图片描述
在Java中,启动main函数时,其实启动的是一个JVM的进程,尔main函数所在的线程是主线程

线程的创建与运行

继承Thread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ThreadTest {

public static class MyThread extends Thread {

private final String message;

public MyThread(String message) {
super();
this.message = message;
}

@Override
public void run() {
System.out.println( message + "MyThread.run()");
}
}

public static void main(String[] args) {
MyThread myThread = new MyThread("这是参数");
myThread.start(); //
}
}

实现Runnable接口的run方法

1
2
3
4
5
6
7
8
9
10
11
12
public class RunableTask implements Runnable{
@Override
public void run() {
System.out.println("RunableTask.run()");
}

public static void main(String[] args) {
RunableTask runableTask = new RunableTask();
new Thread(runableTask).start();
new Thread(runableTask).start();
}
}

FutureTask

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class CallerTask implements Callable<String> {

private final String message;

public CallerTask(String message) {

this.message = message;
}

@Override
public String call() throws Exception {
return message + "hello";
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask = new FutureTask<>(new CallerTask("这是参数"));
new Thread(futureTask).start();
String result = futureTask.get();
System.out.printf(result);
}
}

wait,synchronized,notify,volatile

  • synchronized:当多个线程需要对共享变量进行操作时,为避免同时对变量进行操作所引起的错误,需要使用synchronized()拿到共享变量的监视器锁
  • synchronized内存语意:进入到synchronized块后,使用到该变量时直接从主内存中获取,而不是线程的工作内存,退出synchronized指的是对共享变量的改变刷新到主内存中
  • wait:线程在拿到共享变量的监视器锁后调用wait()函数,使自己挂起停止运行,并释放共享变量的监视器锁
  • notify: 线程在拿到共享变量的监视器锁后调用notify()函数,通知一个线程进入等待状态(由JVM决定)尝试获取共享变量的监视器锁,但此线程还会进行运行,直到线程结束
  • volatile:当一个变量被声明为volatile后,线程会把值刷新到主内存中,当其他线程读取该变量中,会从主内存直接获取

ThreadLocal

在线程中对ThreadLocal赋值时,实际上是调用该线程的线程的ThreadLocalMap中以该线程为key,赋的值的为值来创建当前线程的对应的HashMap,
注意:使用完这些变量后要及时删除,否则可能会造成内存溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ThreadLocalTest {

static void print(String str) {
System.out.println(str + ":" + localVariable.get());
localVariable.remove();
}

static ThreadLocal<String> localVariable = new ThreadLocal<String>();

public static void main(String[] args) {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run() {
localVariable.set("threadOne local variable");
print("threadOne");
System.out.println("threadOne remove after" + ":" + localVariable.get());
}
});

Thread threadTwo = new Thread(new Runnable() {
@Override
public void run() {
localVariable.set("threadTwo local variable");
print("threadTwo");
System.out.println("threadTwo remove after" + ":" + localVariable.get());
}
});

threadOne.start();
threadTwo.start();
}


}