一.概念
1.什么是线程
- 进程的概念
进程是是指可执行程序并存放在计算机存储器的一个指定序列,他是一个动态执行的过程 - 线程是比进程还小的运行单位,一个进程包含多个线程。线程可以看作一个子程序。
二.线程的创建
-
方法一:通过继承Thread类的方式创建线程类,重写run()方法。
代码示例:
package com.imooc.thread;
class MyThread extends Thread{
public void run(){
System.out.println(getName()+"该线程正在执行!");
}
}
public class ThreadTest {
public static void main(String[] args) {
//System.out.println("主线程1");
//创建线程对象
MyThread mt=new MyThread();
mt.start();//启动线程
mt.start();
//System.out.println("主线程2");
}
}
- 方法二:通过实现Runnable接口的方式创建。
代码示例:
package com.imooc.runnable;
class PrintRunnable 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) {
PrintRunnable pr = new PrintRunnable();
Thread t1 = new Thread(pr);
t1.start();
//PrintRunnable pr1 = new PrintRunnable();
Thread t2 = new Thread(pr);
t2.start();
}
}
//为什么要实现Rannable接口:
//1.- Java不支持多继承
//2.不打算重写Thread类的其他方法
三.线程的生命周期
1.线程的状态
- 新建
- 可运行
- 正在运行
- 阻塞
- 终止
2.生命周期
3.Thread类的方法
1.sleep()方法:public static void sleep(long millis)
- 作用:在指定的毫秒数内让正在执行的线程休眠。
- 参数作休眠的时间,单位是毫秒
- 代码实例:
package com.imooc.sleep;
class MyThread 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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class SleepDemo {
public static void main(String[] args) {
MyThread mt=new MyThread();
Thread t=new Thread(mt);
t.start();
Thread t1=new Thread(mt);
t1.start();
}
}
2.join()方法:public final void join()
- 作用:等待调用该方法的线程结束后才能执行。
- 代码实例:
package com.imooc.join;
class MyThread extends Thread{
public void run(){
for(int i=1;i<=500;i++)
System.out.println(getName()+"正在执行"+i+"次!");
}
}
public class JoinDemo {
public static void main(String[] args) {
MyThread mt=new MyThread();
mt.start();
try {
mt.join(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=1;i<=20;i++){
System.out.println("主线程运行第"+i+"次!");
}
System.out.println("主线程运行结束!");
}
}
4.线程优先级
- Java为线程类提供了10个优先级
- 优先级可以用整数1-10表示,超过范围会抛出异常
- 主线程默认优先级为5
- 优先级常量
- MAX_PRIORITY:线程的最高优先级10
- MIN_PRIORITY:线程的最低优先级1
- NORM_PRIORITY:线程的默认优先级5
- 优先级相关的方法
- getPriority() 获取优先级的方法
- setPriority(int newPriority) 设置优先级的方法
- 代码实例:
package com.imooc.priority;
class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name=name;
}
public void run(){
for(int i=1;i<=50;i++){
System.out.println("线程"+name+"正在运行"+i);
}
}
}
public class PriorityDemo {
public static void main(String[] args) {
//获取主线程的优先级
int mainPriority=Thread.currentThread().getPriority();
//System.out.println("主线程的优先级为:"+mainPriority);
MyThread mt1=new MyThread("线程1");
MyThread mt2=new MyThread("线程2");
//mt1.setPriority(10);
mt1.setPriority(Thread.MAX_PRIORITY);
mt2.setPriority(Thread.MIN_PRIORITY);
mt2.start();
mt1.start();
//System.out.println("线程1的优先级为:"+mt1.getPriority());
}
}
四.线程同步
- 线程运行时问题:
- 各个线程是通过竞争CPU时间而获得运行机会的
- 各线程什么时候得到CPU时间,占多久,是不可预测的
- 一个正在运行着的线程在什么地方被暂停是不确定的
-
解决方法:将对象进行锁定,使用关键字synchronized实现
-
synchronized关键字用在
- 成员方法
- 静态方法
- 语句块
代码示例:
public synchronized void saveAccount() {
// 获取当前的账号余额
int balance = getBalance();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 修改余额,存100元
balance += 100;
// 修改账户余额
setBalance(balance);
// 输出存款后的账户余额
System.out.println("存款后的账户余额为:" + balance);
}
五.线程间通信
- wait()方法:中断方法的执行,使线程等待。
- notify()方法:唤醒处于等待的某线程,使其结束等待。
- notifyAll()方法:唤醒所有处于等待的线程,使其结束等待。
- 代码实例:
package com.imooc.queue;
public class Queue {
private int n;
boolean flag=false;
public synchronized int get() {
if(!flag){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("消费:"+n);
flag=false;//消费完毕,容器中没有数据
notifyAll();
return n;
}
public synchronized void set(int n) {
if(flag){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("生产:"+n);
this.n = n;
flag=true;//生产完毕,容器中已经有数据
notifyAll();
}
}