一个进程可以有多个线程
线程是进程的一个可执行单位
线程调度方式
分时调度
抢占式调度
java使用抢占式调度
Thread
线程类
运行线程用start()
,JVM去调用run()
继承Thread
类
public class MyThread extends Thread {
public MyThread() {
//自定义线程名字
super("MyThread");
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("j="+i);
}
}
}
@Test
public void demo(){
MyThread myThread = new MyThread();
myThread.start();
for (int i = 0; i < 1000; i++) {
System.out.println("i======"+i);
}
}
新开的线程一定要在for循环前面,不然就会先打印for循环了然后再开线程了
不要自作聪明直接去调用run()方法
直接调用run()方法会先执行完MyThread 中的for循环,再回来执行剩下的for循环
多次启动同一个线程是非法的
MyThread myThread = new MyThread();
myThread.start();
myThread.start();
线程名字默认从Thread-0
开始,然后是1,2,3…
也可以实现Runnable
接口
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("k..........."+i);
}
}
}
MyRunnable myRunnable = new MyRunnable();
//自定义线程名字MyRunnable
new Thread(myRunnable,"MyRunnable").start();
匿名内部类的方式调用
public void demo1(){
//第一种匿名内部类
new Thread(){
public void run(){
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}.start();
//第二种匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}).start();
}
线程的生命周期
Thread类中sleep(),线程不会释放对象锁,会交出cpu控制权,时间过后会自动争夺cpu控制权
Object类中的wait(),线程会放弃对象锁,会死等,等你使用notify唤醒
synchronized关键字
售票例子:
public class MyTicket implements Runnable {
int ticket=10000;
@Override
public void run() {
while (true){
synchronized (this){
if (ticket>0){
System.out.println(Thread.currentThread().getName()+"" +
"正在售出第"+ticket--+"张票");
}
}
}
}
}
public static void main(String[] args) {
MyTicket myTicket = new MyTicket();
new Thread(myTicket,"窗口一").start();
new Thread(myTicket,"窗口二").start();
new Thread(myTicket,"窗口三").start();
}
锁可以在代码块上(粗粒度锁)
也可以在方法上面(细粒度锁)
普通方法对象 this
静态方法对象 类名.class(字节码对象)
Lock
提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能
我们使用Lock接口,以及其中的lock()
方法和unlock()
方法替代同步,对电影院卖票案例中Ticket类进行如下代码修改
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true){
lock.lock();
if (ticket>0){
System.out.println(Thread.currentThread().getName()+"" +
"正在售出第"+ticket--+"张票");
}
lock.unlock();
}
}