一.线程的概念
用户可以同时使用计算机听歌或打印文件,这种思想在JAVA中称为并发。
线程:并发完成的每一件事情称为线程;
一个程序中的方法有几条执行路径,就有几个线程;
进程:一个进程中可以有多个线程;
并行:多个CPU同时进行多件事情;
二.线程的创建
两种方式:1, 继承Thread类
class TestThread extends Thread {......}
2, 实现Runnable接口, 然后作为参数传入到Thread类的构造方法中
class TestThread implements Runnable {......}
实际开发中多采用第二种方法,因为可以继承其他类和实现多个接口;
线程创建示例:
ackage Test;
public class TestThread {
public static void main(String[] args) {//主线程
Mythread mt = new Mythread();
mt.start();//继承Thread类后调用start方法启动一个线程,该方法会自动执行run()方法,不能直接调用run()方法;
Mythread1 mt1 = new Mythread1();
Thread t = new Thread(mt1);//实例化Thread类,将Runnable的实现类作为参数传入该构造方法中
t.start();//启动另一个线程
for (int i = 0; i < 50; i++) {
System.out.println(i + "----------");
}
}
}
//第一种:继承Thread类,重写里面的run方法
class Mythread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 50; i++) {
System.out.println(i + "===========");
}
}
}
//第二种:实现Runnable接口,重写里面的run方法
class Mythread1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(i + "############");
}
}
}
打印结果:
三.线程状态转换
线程的生命周期是从调用start方法开始到run方法结束;
导致阻塞的事件:比如程序在等待用户操作才能继续执行的情况;
四.线程的常用方法:
1.t.interrupt()---打断线程;t.stop()---终止线程;这两种方法会抛出异常,不推荐使用;
现采用在实现类中定义一个布尔值,需要关闭时改为false即可:
class Mythread1 implements Runnable {
static boolean flag = true;
@Override
public void run() {
while(flag) {
System.out.println(new Date());
}
}
}
2.setPriority()------设置优先级, 优先级的概念: 谁的优先级高, 谁执行的时间就多,默认都为5;
Thread里面的默认优先级:
Thread.MIN_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
3.Thread.sleep(5000)------让线程睡眠5秒钟;
4.Thread.yield()-----线程的礼让,让出CPU执行其他线程;但并不保证一定会礼让;
5.t.join()------线程的加入,当一个线程使用该方法加入另一个线程时,另一个线程会等待该线程执行完毕再继续执行。
6.t.setName;t.getName------设置/获取线程的名字;
7.isAlive()------判断线程是否还活着, 调用start()之前和终止之后都是死的, 其他的都是活的;
五.线程间的通信
1.wait()-----线程等待,使线程从运行状态进入就绪状态;
wait()与sleep的区别:1.调用sleep()方法的线程不释放锁,但wait()方法线程释放锁;
2.wait()方法如不写时间参数会使线程无限等待下去,需要使用notify()或notifyAll()唤醒;
2.notify()------唤醒线程;
3.notifyAll()------唤醒全部线程;
六.线程同步(synchronized)与锁
1.模拟去银行取钱示例
package Test1; public class Bank { private static int money = 3000; public synchronized void getMoney(int cash) { if (money >= cash) { money -= cash; System.out.println("取出了" + cash + "元"); } else { System.out.println("余额不足,剩余" + money + "元"); } } } package Test; import Test1.Bank; public class Test { public static void main(String[] args) { Bank b = new Bank(); Person p1 = new Person(b); Person p2 = new Person(b); Thread t1 = new Thread(p1); Thread t2 = new Thread(p1); t1.start(); t2.start(); } } class Person implements Runnable{ Bank bank; public Person(Bank bank) { super(); this.bank = bank; } @Override public void run() { this.bank.getMoney(2000); } }
2.模拟去车站买票示例
package Test1; public class Piao { private int i = 5; public synchronized void sail(String name) { if(i > 0) { System.out.println(name +"你买了第"+ i-- +"张票"); }else { System.out.println(name +"票卖没了"); } } } package Test1; public class Testpiao implements Runnable { Piao p = new Piao(); @Override public void run() { p.sail(Thread.currentThread().getName());//获取当前线程的名字 } public static void main(String[] args) { Testpiao tp = new Testpiao(); Thread td1 = new Thread(tp); Thread td2 = new Thread(tp); Thread td3 = new Thread(tp); Thread td4 = new Thread(tp); Thread td5 = new Thread(tp); Thread td6 = new Thread(tp); td1.setName("超人"); td2.setName("闪电侠"); td3.setName("蝙蝠侠"); td4.setName("绿巨人"); td5.setName("雷神"); td6.setName("美国队长"); td1.start(); td2.start(); td3.start(); td4.start(); td5.start(); td6.start(); } }
3.死锁示例
package Test1; public class Deadlock implements Runnable { private static Object o1 = new Object(); private static Object o2 = new Object(); private int flag; //两个线程锁住各自对象后都要锁住另一个对象才会解锁原对象,互不相让导致程序一直处于等待状态; @Override public void run() { if (flag == 1) { System.out.println("线程" + flag + "开始"); synchronized (o1) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o2) { System.out.println("线程" + flag + "结束"); } } } if (flag == 2) { System.out.println("线程" + flag + "开始"); synchronized (o2) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o1) { System.out.println("线程" + flag + "结束"); } } } } public static void main(String[] args) { Deadlock d1 = new Deadlock(); Deadlock d2 = new Deadlock(); Thread t1 = new Thread(d1); Thread t2 = new Thread(d2); d1.flag = 1; d2.flag = 2; t1.start(); t2.start(); } }