1、线程API
-
sleep(x) 当前线程睡眠x秒以后,进入就绪状态
Thread.sleep(1000); //当前线程睡眠1秒
-
join() 加入某个线程
MyThread my = new MyThread(); //某个线程 my.start(); //启动某个线程 my.join();//当前线程停止,等待my线程执行完毕 System.out.println("这句话,会等到my线程中的run方法执行完毕后才会执行");
-
stop() 直接调用该线程的stop()方法来结束该线程,已淘汰,会引发死锁
2、守护线程
- JVM进程,必须所有的线程都结束,守护进程才结束。
- Java的线程分两种
UserThread(用户线程)
DaemonThread(守护线程):GC(垃圾回收器)就是一个很称职的守护者
User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果 User Thread已经全部退出运行了,只剩下Daemon Thread存在了,虚拟机也就退出了。 因为没有了被守护者,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。
3、多线程下进行Debug(eclipse)
- main方法: (主线程,是一个用户线程),其他线程可以在他后面结束。
4、线程的安全
- 线程访问临界资源(共享资源)问题
- 需要加锁; 并不是对临界资源本身去上锁; 而是对访问这个资源的代码去上锁;
4.1 syschronized(同步的) 锁住代码块.同步代码块
syschronized(对象){
//代码块
}
同一个时间片,只有一个线程来访问这个代码块.
4.2 synchronized
public synchronized void meth(){ //同步方法.
}
多个线程来访问这个方法的时候, 同一个时间片,只有一个线程来访问这个方法
5、多线程实例(多窗口卖车票)
package com.qianfeng.ljf.test;
public class TicketThreadTest {
public static void main(String[] args) {
SellTicketThread stt1 = new SellTicketThread("窗口1");
SellTicketThread stt2 = new SellTicketThread("窗口2");
SellTicketThread stt3 = new SellTicketThread("窗口3");
SellTicketThread stt4 = new SellTicketThread("窗口4");
SellTicketThread stt5 = new SellTicketThread("窗口5");
stt1.start();
stt2.start();
stt3.start();
stt4.start();
stt5.start();
}
}
class SellTicketThread extends Thread {
private static int ticket = 100; //车票数,全局唯一
public SellTicketThread() {}
public SellTicketThread(String name) {
super(name);
}
@Override
public void run() {
while (ticket > 0) {
try {
Thread.sleep(1000); //休眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized ("suo") {
if (ticket > 0) { //当有多个阻塞的线程拿到锁时,票数小于等于0时不执行
System.out.println(getName()+":卖出车票"+ticket--);
}else{
System.out.println("车票已售完");
System.exit(0);
}
}
}
}
}