java多线程基础
1. 线程的创建
两种方法:继承Thread,实现runable.
1.1 继承Thread 重写run方法
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("do someThing");
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
1.2 实现runable
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("do someThing");
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
}
}
2. 常用方法
2.1 currentThread()
静态方法,返回对当前正在执行的线程对象的引用
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
2.2 start()
启动线程,和run()方法的区别,使用run()方法并没有真的启动线程而start方法是真正启动了线程
2.3 yield()
让出对当前处理器的占有,程序调度的时候有可能继续运行这个线程。
Thread.yield();
2.4 sleep()
让当前线程睡眠一段时间
public static void main(String[] args) {
Thread t = new Thread() {
@Override
public void run() {
System.out.println("sleep...");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sleep complete");
}
};
t.start();
}
2.5 join()
使当前线程等待该线程执行完毕
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
@Override
public void run() {
System.out.println("sleep...");
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sleep completed");
}
};
t.start();
System.out.println("join");
t.join();
System.out.println("join completed");
}
2.6 wait/notify
1.wait()/notify()必须在synchroized中 否则会报错
2.当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。
3.当执行notify方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁
4.notifyAll方法和nofity类似,但notifyAll会唤醒所有等待的线程
public class WaitAndNotify {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread tw = new Thread(){
@Override
public void run() {
while(true) {
try {
synchronized (lock) {
System.out.println("wait...");
lock.wait();
System.out.println("wait");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread tn = new Thread(){
@Override
public void run() {
while(true) {
try {
sleep(1000L * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
System.out.println("notify");
lock.notify();
}
}
}
};
tw.start();
tn.start();
}
}
3. 线程状态
-
新建(NEW)
表示线程被创建出来还没真正启动的状态。 -
就绪(RUNNABLE)
表示该线程已经在 JVM 中执行,可能是正在运行,也可能还在等待系统分配给它 CPU 片段,在就绪队列里面排队。 -
阻塞(BLOCKED)
表示线程在等待Monitor lock。比如,线程试图通过 synchronized 去获取某个锁。 -
等待(WAITING)
表示正在等待其他线程采取某些操作。比如当前线程调用wait()方法等待其他线程notify。Thread.join() 也会令线程进入等待状态。 -
计时等待(TIMED_WAIT)
和等待状态类似,但是调用的是存在超时条件的方法,比如 wait 或 join 等方法的指定超时版本。 -
终止(TERMINATED)
线程已经完成使命,终止运行。
其他
守护线程和用户线程
使用setDaemon(true)方法设置线程为守护线程,守护线程的特点是当进程中只剩下守护线程时,所有守护线程强制终止。GC就是运行在一个守护线程上的。
线程的优先级
setPriority()可以设定线程的优先级,优先级高的有更大的几率优先执行。
java中线程优先级可以指定范围1~10(但是并不是所有的操作系统都支持10级划分)。java只是给操作系统一个参考值,线程在操作系统的优先级还是由操作系统决定,默认优先级是5。