JavaSE:多线程

206 阅读3分钟

001.进程和线程关系

线程是比进程还要小的运行单位,一个进程包含多个线程

002.线程的创建

0021.创建方式:

  • 继承Thread类
  • 实现Runnable接口(推荐)
  • 实现Callable接口

0022.Thread类

  • Thread 是一个线程类,位于java.lang包下,继承Runnable接口,重写run方法;
  • Thread.currentThread().getName() 线程名
  • Thread常用方法:
public void run()                   线程相关代码写在该方法中
public voif start()                 启动线程
public static void sleep(long m)    线程休眠,单位毫秒
public void join()                  优先执行调用join()方法的线程
//代码
class MyThread extends Thread{
    public void run(){
    	for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+"线程:"+i);
    	}
    }
}

public class TestThread {

    public static void main(String[] args) {
    	MyThread t1 = new MyThread();
    	t1.start();
    	MyThread t2 = new MyThread();
    	t2.start();
    }
}

0023.Runnable接口

class MyRunnable implements Runnable {
    int i= 1;
    @Override
    public void run() {
    	while(i<=10){
        	System.out.println(Thread.currentThread().getName()+"线程:"+(i++));
    	}
    }
}

public class Test {
    public static void main(String[] args) {
    	MyRunnable r = new MyRunnable();
    	Thread t1 = new Thread(r);
    	t1.start();
    	Thread t2 = new Thread(r);
    	t2.start();
    }
}

0024.Callable接口

  • Callable在Java1.5中引入,会返回结果或抛出异常;

0025.实现接口 vs 继承 Thread

  • 推荐接口
  • Java不支持多继承,因此继承了Thread类就无法继承其它类,但是可以实现多个接口;

003.线程的状态和生命周期

0031.线程的状态

  • 新建(New)
  • 可运行(Runnable)
  • 正在运行(Running)
  • 阻塞(Blocked)
  • 终止(Dead)

0032.生命周期图

0033.sleep方法应用

class TestSleep implements Runnable{
    @Override
    public void run() {
    	for(int i=1;i<=30;i++){
    		System.out.println(Thread.currentThread().getName()+"执行第"+i+"次");
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
}

public class TestDemo {
    public static void main(String[] args) {
    	TestSleep ts = new TestSleep();
    	Thread t1 = new Thread(ts);
    	t1.start();
    }
}

00343.join方法应用

lass MyThread implements Runnable{
    @Override
    public void run() {
    	for(int i=1;i<=10;i++){
    		System.out.println(Thread.currentThread().getName()+"运行第"+i+"次!");
    	}
    }
}

public class JoinDemo {
	public static void main(String[] args) {
            MyThread mt = new MyThread();
            Thread t1 = new Thread(mt);
            t1.start();
            try {
            	t1.join();
            } catch (InterruptedException e) {
            	e.printStackTrace();
            }
            for(int i=0;i<=20;i++){
            	System.out.println("主线程运行第"+i+"次!");
            }
            System.out.println("主线程运结束!");
	}
}

004.线程的优先级

  • Java为线程类提供了10个优先级
  • 优先级可以用整数1-10表示,超过范围会抛出异常
  • 主线程默认优先级为5
  • MAX_PRIORITY:线程的最高优先级10
  • MIN_PRIORITY:线程的最低优先级1
  • NORM_PRIORITY:线程默认值优先级5
  • 方法
    • public iny getPriority() 确定线程的优先级
    • public void setPriority(int newPriority) 设置线程的优先级

005.互斥同步

Java提供了两种锁机制来控制多个多线程对共享资源的互斥访问,第一个是JVM实现的synchronized,而另一个是JDK实现的ReentrantLock(重入锁

0051.关键字synchronized

//成员方法上锁
public synchronized void saleTicket(){...}
//静态方法
public static synchronized void saleTicket(){...}
//语句块
synchronized(obj){...}

0052.ReentrantLock

  • ReentrantLock 是 java.util.concurrent(J.U.C)包中的锁
public void saleTicket(){
	lock.lock();
	...
	lock.unlock();
}

0053.线程同步的一些例子

  • 银行存取款
  • 12306抢票

006.线程间通信

0061.涉及的方法

  • wait 中断方法的执行,使线程等待
  • notify() 唤醒处于等待的某个线程,使其结束等待
  • notifyAll() 唤醒所有处于等待的线程,使它们结束等待

0062.例子:

  • 生产者和消费者

007.一些区别

0071.wait() 和 sleep() 区别?

  • sleep方法没有释放锁,而wait方法释放了锁;
  • wait方法是Object的方法,而sleep方法是Thread的静态方法;
  • wait通常被用于线程间交互/通信,sleep通常被用于暂停执行;
  • wait方法被调用后,线程不会自动苏醒,需要调用notify()或notifyAll()方法,或者(使用wait(long timeout)超时后线程会自动苏醒);而sleep方法执行完成后,线程会自动苏醒;