1、进程和线程的区别
进程:程序一次动态加载的过程,代码执行到执行完毕的一个过程
线程:比进程更小的单元,
1.2java线程的五种状态
新建(new):如:Thread t = new MyThread();
就绪(Runnable):t.start()线程进入就绪状态,随时准备cpu调度
运行(Runing):cpu开始调度处于就绪状态的线程
阻塞(Blocked):运行状态的线程由于某种原因,放弃对cpu的使用权,进入阻塞状态
1.等待阻塞:线程执行wait()方法
2.同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
3.其他阻塞:sleep()或者join()
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
2、线程实现的三种方式
2.1实现Runnable接口
public class MyThread01 implements Runnable {
private String name;
public MyThread01(String name){
this.name = name;
}
public static void main(String[] args) {
MyThread01 myThread01A = new MyThread01("线程A");
MyThread01 myThread01B = new MyThread01("线程B");
Thread thread1 = new Thread(myThread01A);
Thread thread2 = new Thread(myThread01B);
thread1.start();
thread2.start();
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name+"运行了,i="+i);
}
}
}
2.2继承Thread类
public class MyThread02 extends Thread{
public String name;
public MyThread02(String name){
this.name = name;
}
public static void main(String[] args) {
MyThread02 myThread01 = new MyThread02("线程A");
MyThread02 myThread02 = new MyThread02("线程B");
myThread01.start();
myThread02.start();
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name +"运行了,i = "+i);
}
}
}
2.3实现Callable
public class MyCallable implements Callable<Integer> {
private String name;
private int number;
public MyCallable(String name,int number){
this.name = name;
this.number = number;
}
@Override
public Integer call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println(name+"运行了,i="+i);
}
return number;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> ft1 = new FutureTask<>(new MyCallable("线程1",3));
FutureTask<Integer> ft2 = new FutureTask<>(new MyCallable("线程2",4));
Thread thread1 = new Thread(ft1);
Thread thread2 = new Thread(ft2);
thread1.start();
thread2.start();
Integer number1 = ft1.get();
Integer number2 = ft2.get();
System.out.println("线程一返回结果:" + number1);
System.out.println("线程二返回结果:" + number2);
}
}
三种实现方式的对比:
- 继承Thread类:编写简单,由于java只能单一继承,所以该方式不够灵活
- 实现Runnable接口:从JDK1.0开始,通过实现接口,省去了单继承的弊端,可以让我们更加灵活地编写代码
- 实现Callable接口:从JDK1.5开始,最大的好处,可以有返回值
Thread 类和 Runnable 接口
通过 Thread 类和 Runable 接口都可以实现多线程,那么两者有哪些联系和区别呢?下面我们观察 Thread 类的定义。
public class Thread extends Object implements Runnable
从 Thread 类的定义可以清楚的发现,Thread 类也是 Runnable 接口的子类,但在Thread类中并没有完全实现 Runnable 接口中的 run() 方法,下面是 Thread 类的部分定义。
3、java中同步的关键字(synchronzied)
synchronzied关键字用来同步块的。所有同步在一个对象上的同步块在同时只能被一个线程并行操作,所有等待进入该同步块的线程被阻塞,直到执行到同步块中的线程被退出。
4、四种不同的同步块
4.1实例方法同步
public synchronized void add(int value){
this.count += value;
}
4.2静态方法同步
public static synchronized void add(int value){
count += value;
}
4.3实例方法中的同步块
public void add(int value){
synchronized(this){
this.count += value;
}
}
4.4静态方法中的同步块
public class MyClass {
public static synchronized void log1(String msg1, String msg2){
log.writeln(msg1);
log.writeln(msg2);
}
public static void log2(String msg1, String msg2){
synchronized(MyClass.class){
log.writeln(msg1);
log.writeln(msg2);
}
}
}