1、基本知识:
进程:一个正在进行的程序。每个进程都有一个执行顺序,或者叫做控制单元。每个进程都有自己独立的内存空间。
线程:完成某个特定功能的代码,进程中的一个独立的控制单元,线程控制着进程的执行。一个进程中至少有一个线程。多个线程共享的是同一快内存空间。JVM启动时,会有一个进程java.exe,该进程中至少有一个线程负责java程序的执行,并且这个线程是主线程,运行的代码在main()方法中。
在某一时刻,只能有一个程序在运行,cpu在做着快速的切换,以达到看上去同时运行的效果,多个线程在抢占cpu的使用权。这是多线程的随机性。
2、继承thread类后,为什么要重写run方法?
因为thread类用于描述线程,其run方法用来存储自定义的代码。start方法:开启线程并调用执行run方法
run方法:仅仅是对象调用方法,线程虽然创建了,但是并没有执行。
<span style="font-family:Comic Sans MS;font-size:18px;">package Thread;
/**
* 两种显示线程名称的方法:
* 1、this.getName()方法
* 2、Thread.currentThread().getName()
* @author USER
*
*/
class ShowThreadName extends Thread{
//通过调用父类无参构造方法显示默认线程名
public ShowThreadName() {
// TODO Auto-generated constructor stub
super();
}
//通过调用父类有参构造方法设置线程名
public ShowThreadName(String name) {
super(name);
}
public void run() {
System.out.println(this.getName());
System.out.println(Thread.currentThread().getName());
}
}
public class ShowThreadNameMain {
public static void main(String[] args) {
ShowThreadName name1 = new ShowThreadName();
ShowThreadName name2 = new ShowThreadName("hello");
//start()方法启动了新的线程
name1.start();//Thread-0、hello
name2.start();//Thread-0、hello
//run()方法没有启动新的线程,所以还是主线程main
name1.run();//Thread-0、main
name2.run();//hello、main
}
}
</span>
3、线程的四种状态:
新建(new):线程被创建时,状态很短暂,此刻线程有资格获得cpu时间就绪(runnable):线程获得时间就可以执行。
阻塞:阻止线程运行,有运行资格,但没有运行权
死亡:线程结束,stop方法
4、创建线程的两种方法:
<1>继承Thread类,重写run方法,新建创建的子类对象,调用start()方法,即创建并启动了一个线程。<2>实现runnable接口,重写run方法,创建Thread类对象,并将实现runnable接口的子类对象作为参数传递给Thread类的对象,
调用Thread类的start方法,启动线程并调用runnable接口的子类的run方法。
二者区别:实现方式避免了单线程的局限性。二者的线程执行的代码存放的位置不同的run方法中。5、多线程的安全问题---同步机制
多线程的安全问题:多个线程共享同一个共享数据,每个线程被cpu随进分配时间访问
解决方法:同步机制synchronized后,共享数据顺序输出,同步后只有一个线程执行。
synchronized相当于锁,有两种同步机制:
1、同步代码块:synchronized(对象){},对象可以是this或其它对象(如object对象)
2、同步方法:synchronized 方法名{},同步的是调用该方法的this对象
静态同步方法:使用的锁是该方法所在类的字节码对象,类名.Class
<span style="font-family:Comic Sans MS;font-size:18px;">package Thread;
class Test1 implements Runnable{
int a = 100;
Object obj = new Object();
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized (obj) {
if (a>0) {
System.out.println(Thread.currentThread().getName()+"---"+a--);
}
}
}
}
}
public class ThreadSecurity {
public static void main(String[] args) {
Test1 t = new Test1();
Thread th1 = new Thread(t);
Thread th2 = new Thread(t);
Thread th3 = new Thread(t);
Thread th4 = new Thread(t);
th1.start();
th2.start();
th3.start();
th4.start();
}
}
</span>
6、 wait()、notify()、notifyAll()方法用于协调多个线程对共享数据的分配
其中wait()方法必须在同步方法或同步代码块中,wait()方法让已经获得了同步方法或同步代码块控制权的
Thread暂时休息,并且丧失了控制权而等待,让其他线程取得控制权并执行