1. 线程创建的四种方式
继承Thread类
/*** 继承Thread类*/public class ThreadDemo1 extends Thread {@Overridepublic void run(){System.out.printf("线程[ %1$s],以继承父类Thread的方式实现的线程正在运行中.... \n",Thread.currentThread().getName());}}// 启动线程public static void main(String[] args) {new ThreadDemo1().start();}
实现Runnable接口
/*** 实现runnable接口实现*/public class ThreadDemo2 implements Runnable{@Overridepublic void run() {System.out.printf("线程[ %1$s],以实现runnable接口的方式实现的线程正在运行中.... \n",Thread.currentThread().getName());}}// 启动线程public static void main(String[] args) {new Thread(new ThreadDemo2()).start();}
实现Callable<>接口
/*** 实现Callable<T>接口实现,带返回值*/public class ThreadDemo3<S> implements Callable<String>{@Overridepublic String call() throws Exception {System.out.printf("线程[ %1$s],以实现 * 实现Callable<T>接口的方式实现的线程正在运行中.... \n",Thread.currentThread().getName());return "我是返回值" ;}}// 启动线程public static void main(String[] args) {ThreadDemo3<Object> threadDemo3 = new ThreadDemo3<>();FutureTask<String> futureTask = new FutureTask<>(threadDemo3);new Thread(futureTask).start();System.out.println(futureTask.get());}
Executors线程池
//创建并启动线程public static void main(String[] args) {//线程池创建的方式AExecutorService executorServiceA = Executors.newFixedThreadPool(4);//线程池创建方式B[实际开发工作中-推荐]ThreadPoolExecutor threadPoolExecutorB = new ThreadPoolExecutor(4, 4, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(8));//创建线程executorServiceA.execute(new ThreadDemo1());executorServiceA.submit(new ThreadDemo3());threadPoolExecutorB.execute(new ThreadDemo1());threadPoolExecutorB.submit(new ThreadDemo3());//关闭线程池 shutdown()executorServiceA.shutdown();threadPoolExecutorB.shutdown();}
2. 线程的状态和状态转换
NEW
Thread state for a thread which has not yet started.
通过new Thread()的方式创建一个线程
RUNNABLE
Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
通过调用创建的线程的start()方法,使得线程处于就绪状态
处于RUNNABLE状态的线程,抢占cpu时间片,获取cpu时间片或执行run()方法内的逻辑
BLOCKED
Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling [Object.wait].
调用Object.wait()方法,阻塞当前线程
WATING
Thread state for a waiting thread. A thread is in the waiting state due to calling one of the following methods:
[Object.wait] with no timeout
[Thread.join] with no timeout
[LockSupport.park]
A thread in the waiting state is waiting for another thread to perform a particular action.
TIMED_WATING
Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:
[Thread.sleep]
[Object.wait]
[Thread.join]
[LockSupport.parkNanos]
[LockSupport.parkUntil]
TERMINATED
Thread state for a terminated thread. The thread has completed execution.
3. 线程同步
线程安全问题往往是伴随着多线程操作共享资源资源而产生的,通过线程同步解决线程问题
以银行账户的存取钱,来演示线程同步问题;分别采用synchronized关键字和Lock实现线程安全
3.1 关键字synchronized
public class BankThreadTest {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);Account account = new Account("Golphin", 0L);executorService.execute(()-> {try {Thread.sleep(100L);} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < 3; i++) {account.deposit(1000);}});executorService.execute(() ->{try {Thread.sleep(100L);} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < 3; i++) {account.draw(200);}});executorService.shutdown();}}@AllArgsConstructor@Dataclass Account{private String accountName;private double balance;//存款public synchronized void deposit(double money){if(money>0){this.balance+=money;System.out.printf("线程[%1$s]-操作[存款%2$s]-余额[%3$s]... \n",Thread.currentThread().getName(),money,this.balance);}}//取款public synchronized void draw(double money){if( money>0 && this.balance>money){this.balance-=money;System.out.printf("线程[%1$s]-操作[取款%2$s]-余额[%3$s]... \n",Thread.currentThread().getName(),money,this.balance);}else {System.out.println("当前余额不足");}}}
