线程简介
//Process 进程
//Thread 线程
线程创建
/*
三种创建方式
1. Thread class(继承Thread类)
2. Runnable接口(实现Runnable接口)
3. Callable接口(实现Callable接口)
*/
//1.创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
public testThread1 extends Thread{
public class Test1 extends Thread {
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 200; i++) {
System.out.println(i + "A线程执行!");
}
}
public static void main(String[] args) {
//main线程,主线程
//创建一个线程对象
Test1 testThread1 = new Test1();
//调用start方法开启线程
testThread1.start();
for (int i = 0; i < 1000; i++) {
System.out.println(i + "main线程执行!");
}
}
}
//2.创建线程方式二:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class Test3 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("B线程执行!");
}
}
public static void main(String[] args) {
//创建runnable接口的实现类对象
Test3 test3 = new Test3();
//创建线程对象,通过线程对象来开启我们的线程,代理
//Thread thread = new Thread();
//thread.start();
//创建代理类对象并启动
new Thread(test3).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main线程执行!");
}
}
/*3.创建线程方式三:
1.实现Callable接口,需要返回值类型
2.重写call方法,需要抛出异常
3.创建目标对象
4.创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
5.提交执行: Future<Boolean> result1 = ser.submit(t1);
6.获取结果: boolean r1 = result1.get();
7.关闭服务: ser.shutdownNow();
*/
/*
PS.静态代理模式总结
真实对象和代理对象都要实现同一接口
代理对象要代理真实角色
好处:1代理对象可以做很多真实对象做不了的事情
2真实对象专注做自己的事情
*/
-
线程终止
/*
1.建议线程正常停止——>利用次数,不建议死循环
2.建议使用标志位——>设置一个标志位
3.不要使用stop或destroy等或者JDK不建议使用的方法
*/
package TestThread.Test9;
public class TestStop implements Runnable {
private boolean flag = true;//使用标识位来控制线程的停止
@Override
public void run() {
int i = 0;
while (flag) {
System.out.println("Thread2 run number:" + i++);
}
}
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
TestStop testStop = new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 600; i++) {
System.out.println("main thread in " + i);
if(i == 500){
testStop.stop();
System.out.println("Thread2 over");
}
}
}
}
-
线程休眠
/*
1.sleep(时间)指定当前线程阻塞的毫秒数
2.sleep存在异常InterruptedException
3.sleep时间达到后线程进入就绪状态
4.可以模拟网络延时,倒计时等
5.每一个对象都有一个锁,sleep不会释放锁
*/
//模拟网络延时的作用:放大问题的发生性
-
线程礼让
//礼让线程,让当前正在执行的线程暂停,但不阻塞
//将线程从运行状态转为就绪状态
//让cpu重新调度,礼让不一定成功
package TestThread.Test10;
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程开始执行");
Thread.yield();
System.out.println(Thread.currentThread().getName() + "线程结束执行");
}
}
-
Lambda表达式
/*Functional Interface(函数式接口)
函数式接口的定义:
1.任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口
public interface Ruunable {
public abstract void run();
}
2.对于函数式接口,我们可以通过lambda表达式来创建该接口的对象
*/
like = ()->{
System.out.println("I like lambda5");
};
like.lambda();
//可以在()内加上参数
like2 = (int a)->{
System.out.println(a);
};
like2.lambda(2);
//可以将参数类型去掉,只有一个参数时可以将()省略
like2 = a->{
System.out.println(a);
};
like2.lambda(2);
-
并发初步
//问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
//eg.
public class Test4 implements Runnable{
private int ticketNum = 10;
@Override
public void run() {
//模拟延迟
while(ticketNum > 0){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticketNum-- + "票");
}
}
public static void main(String[] args) {
Test4 ticket = new Test4();
new Thread(ticket, "小明").start();
new Thread(ticket, "小花").start();
new Thread(ticket, "小亮").start();
}
}
//出现多个人获得同张票的情况,且出现了第0张