多线程
1.线程的实现
1.1 继承了thread类
继承了thread类的类,需要重写run方法,run下为一条新的执行路径,外部调用这个方法,需要新建一个Thread对象,调用其start方法,与其他线程运行无先后顺序,抢占线程。
public static void main(String[] args) {
Thread t1 = new MyThread1();
Thread t2 = new MyThread2();
/*
* 启动线程,使其并发运行.
* 注:启动线程要调用start方法,而不是run方法!
*/
t1.start();
t2.start();
}
1.2 实现 runnable 接口
public static void main(String[] args) {
//创建线程任务
Runnable r1 = new MyRunnable1();
Runnable r2 = new MyRunnable2();
//创建线程
Thread t1 = new Thread(r1);
t1.start();
}
}
class MyRunnable1 implements Runnable{
public void run() {
for(int i=0;i<1000;i++) {
System.out.println("你是谁啊?");
}
}
}
1.3 匿名内部类
thread方式
Thread t1 = new Thread() {
public void run() {
for(int i=0;i<1000;i++) {
System.out.println("你是谁啊");
}
}};
Thread t1 = new Thread(r1);
t1.start();
runnable方式
Runnable r2 = new Runnable() {
public void run() {
for(int i=0;i<1000;i++) {
System.out.println("我是查水表的!");
}
}};
Thread t2 = new Thread(r2);
t2.start();
1.4 实现runnable与继承 thread 相比有如下优势
-
可以通过创建任务,然后给线程分配的方式来实现多线程,更适合多个线程同时执行相同任务的情况。
-
可以避免单继承所带来的局限性。
-
任务与线程本身是分离的,提高了程序的健壮性。
2. 获取线程的信息
Thread t = new Thread();
//方法
t.start(); //线程启动
t.setName("自定义名称"); //设置线程名称
String name = t.getName(); //获取线程名称
long id = t.getId(); //获取唯一标识
int pri = main.getPriority(); //获取优先级
Thread t.currentThread(); //返回当前线程对象
t.setDaemon(); //设置守护线程
//判断
boolean isAlive = main.isAlive(); //判断线程是否存活
boolean isDaemon = main.isDaemon(); //判断是否为守护线程
boolean isInter = main.isInterrupted(); //判断线程是否被中断了
2.协同工作
1.线程休眠 / 切换
t.sleep(休眠时间(毫秒)); //线程休眠
t.yield(); //线程切换
//调用次方法的线程阻塞,直到该方法所属的线程结束时解除阻塞状态.
t.join(); //在此线程运行完之前,线程不释放
2.线程优先级
线程有10个优先级,分别用整数1-10表示.其中1为最低优先级,5为默认优先级,10为最高优先级,优先级越高的线程获取CPU时间片的次数越多.
Thread t = new Thread();
t.setPriority(); //优先级设置
3.多线程并发安全问题解决方案
当多个线程并发操作同一临界资源时,由于线程切换时机不确定,导致操作代码执行顺序未按照设计意图执行所导致的操作混乱,严重时可能导致系统瘫痪.
临界资源:同一时间只允许一条线程操作的资源
1.同步方法(隐式锁)
当一个方法被synchronized修饰后,该方法称为同步方法,即:多个线程不能同时在方法内部执行.将并发操作改为同步操作就能有效的解决多线程的并发安全问题了.(把抢改为排队)
2.同步块(隐式锁)
使用同步块可以更精准的控制需要排队的代码片段.但是同步块要求必须指定同步监视器对象,该对象可以是java中任何类的实例,只要保证多个需要同步执行该代码片段的线程看到的是"同一个"即可.
synchronized(锁对象){
}
3.显式锁
Lock l = new ReetrantLock();
l.lock();
//锁内容
l.unlock();