Java并发基础总结

Java多线程基础

Java实现多线程基础主要有两种你手段,一种是集成Thread类,一种是实现Runable接口。还有一种实现Callable接口。后面再说,今天主要讲一下前两个

继承Thread类

这种比较简单,如果没有什么特殊需求,就可以这样实现一个多线程

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
/**
* ThreadDemo
*/
public class ThreadDemo extends Thread{
private String name;
public ThreadDemo(String name){
this.name=name;
}
public void run(){
for(int i=0;i<5;i++){
System.out.println(name+"运行: "+i);
try {
Thread.sleep((int)Math.random()*100);
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
ThreadDemo myThread1 = new ThreadDemo("LaoBo");
ThreadDemo myThread2 = new ThreadDemo("xiaoqin");
myThread1.start();
myThread2.start();
}

}

运行结果

实现Runable接口,重写run方法

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
/**
* RunableDemo
*/
public class RunableDemo implements Runnable{
private String name;
public RunableDemo(String name){
this.name=name;
}

public static void main(String[] args) {
RunableDemo RunThread1 = new RunableDemo("laobo");
RunableDemo RunThread2 = new RunableDemo("xiaoqin");
new Thread(RunThread1).start();
new Thread(RunThread2).start();
}

@Override
public void run() {
for(int i=0;i<5;i++){
System.out.println(name+"运行:"+i);
try {
Thread.sleep((int)Math.random()*100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

运行结果

总结实现Runable接口比继承Thread类所具有的优势

  • 适合多个相同的程序代码的线程去处理同一资源
  • 可以避免Java中单继承的限制
  • 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
  • 线程池只能放入实现Runable或Callable类的线程,不能直接放入继承Thread的类。

常用函数说明

  1. Thread.sleep(long millis): 在指定的毫秒数内让当前正在执行的线程休眠。(暂停执行)
  2. Thread.join()的作用是等待该线程终止,该线程指的是主线程等待子线程的终止。也就是在子线程调用join()方法后面的代码,只有等到子线程结束了才能执行。
  3. Thread.yiled()方法作用是暂停正在执行的对象,并执行其他的线程。但是yiled()做的是让当前线程回到可运行的状态,以允许具有相同优先级的其他线程获得运行机会。所以有时候可能没有效果,因为被yiled()的线程会再次拿到时间片。
  4. interrupt()不是中断某个线程,只是发送一个中断信号,让线程从一个无限等待中抛出。从而结束线程。
  5. Obj.wait()和Obj.notify()必须要和synchronize(Obj)一起使用。也就是说Obj.wait()和Obj.notify()必须在synchronize(Obj){}语法块中。下面一个经典的面试题说明一下。三线程打印交替打印ABC.
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
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* PrintABC
*/
public class PrintABC implements Runnable{
private String name;
private Object pre;
private Object self;
private PrintABC(String name, Object pre, Object self){
this.name=name;
this.pre=pre;
this.self=self;
}
@Override
public void run() {
int count=10;
while(count>0){
synchronized(pre){
synchronized(self){
System.out.print(name);
count--;
self.notify();
}
try {
pre.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();
PrintABC threadA = new PrintABC("A", c, a);
PrintABC threadB = new PrintABC("B", a, b);
PrintABC threadC = new PrintABC("C", b, c);
new Thread(threadA).start();
Thread.sleep(100);
new Thread(threadB).start();
Thread.sleep(100);
new Thread(threadC).start();
Thread.sleep(100);

}

}