1.新建
2.就绪
3.运行
4.阻塞
5.死亡
1.新建->就绪
start()方法
2.就绪->运行
获取cpu执行权
3.运行->就绪
失去cpu执行权
yield()方法
4.运行->阻塞
sleep(long time)
suspend() 已弃用
join()
等待同步锁
wait()
5.阻塞->运行
sleep结束
jion对应的线程结束
resume() 对应于suspend 已弃用
获取同步锁
notify() notifyAll()
6.运行->死亡
run()方法结束
stop()方法
出现error或者exception
sychronized(同步监视器,即锁){
//操作共享数据的代码
}
锁的要求:任意一个对象都可以充当锁,但是所有线程必须共用一个锁
package com.exer;
/**
* @author ym
* @create 2022-01-24 20:45
* @description
*/
public class TicketDemo1 {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread);
Thread thread2 = new Thread(myThread);
Thread thread3 = new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
}
}
class MyThread implements Runnable {
public int tickets = 100;
public Object obj = new Object();
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
while (true) {
//此处加上了同步代码块
synchronized (obj) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "\t" + tickets);
tickets--;
} else {
break;
}
}
}
}
}
package com.exer;
/**
* @author ym
* @create 2022-01-24 20:12
* @description 三个窗口卖票问题
*/
public class TicketDemo {
public static int tickets = 100;
public static void main(String[] args) {
TicketSell ticketSell1 = new TicketSell();
TicketSell ticketSell2 = new TicketSell();
TicketSell ticketSell3 = new TicketSell();
ticketSell1.start();
ticketSell2.start();
ticketSell3.start();
}
}
class TicketSell extends Thread {
@Override
public void run() {
while (true) {
synchronized (TicketSell.class) {
if (TicketDemo.tickets > 0) {
TicketDemo.tickets--;
System.out.println(TicketDemo.tickets + "\t" + getName());
} else {
break;
}
}
}
}
}
如果某一方法全部涉及处理共享数据,则可将此方法设置为同步方法,但是需注意,实现runnable接口方法创建的线程与继承Thread方法在同步方法上略有不同
实现runnable()接口方法创建的线程可以直接同步,但是继承Thread()方法实现的线程在同步方法时需要设置为static,原理:
同步方法也是需要同步监视器的,只不过不需显式指明。如果是非static方法,则同步方法的同步监视器是对象,如果是static方法,则同步方法的同步监视器是类
package com.exer2;
/**
* @author ym
* @create 2022-01-24 20:12
* @description 三个窗口卖票问题
*/
public class TicketDemo {
public static int tickets = 100;
public static void main(String[] args) {
TicketSell ticketSell1 = new TicketSell();
TicketSell ticketSell2 = new TicketSell();
TicketSell ticketSell3 = new TicketSell();
ticketSell1.start();
ticketSell2.start();
ticketSell3.start();
}
}
class TicketSell extends Thread {
@Override
public void run() {
while (true) {
show();
}
}
public static synchronized void show() {
if (TicketDemo.tickets > 0) {
TicketDemo.tickets--;
System.out.println(TicketDemo.tickets + "\t" + Thread.currentThread().getName());
}
}
}
package com.exer2;
/**
* @author ym
* @create 2022-01-24 20:45
* @description
*/
public class TicketDemo1 {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread);
Thread thread2 = new Thread(myThread);
Thread thread3 = new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
}
}
class MyThread implements Runnable {
public int tickets = 100;
public Object obj = new Object();
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
while (true) {
show();
}
}
public synchronized void show() {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "\t" + tickets);
tickets--;
}
}
}
/**
* @author ym
* @create 2022-01-25 11:10
* @description 线程安全的效率较高的单例模式之懒汉式
*/
public class Sluggard {
private Sluggard() {
}
public static Sluggard instanse = null;
public Sluggard getInstanse() {
if (instanse == null) {
//如果是空,那么在下面同步代码块里进行操作,
// 如果不是空,不需同步代码块,直接返回已经生成好了的实例即可
synchronized (Sluggard.class) {
instanse = new Sluggard();
}
}
return instanse;
}
}
它的本质是由于同步机制引起的,不同的线程占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源
解决方法:
1.专门的算法、原则
2.尽量减少同步资源的定义
3.尽量避免嵌套同步
此方法有个疑惑,写在前面,我在测试用继承Thread方法实现的线程时,并未实现同步效果,目前未想出原因,将代码也贴在下面
package com.lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author ym
* @create 2022-01-24 20:12
* @description 三个窗口卖票问题
*/
public class TicketDemo {
public static int tickets = 100;
public static void main(String[] args) {
TicketSell ticketSell1 = new TicketSell();
TicketSell ticketSell2 = new TicketSell();
TicketSell ticketSell3 = new TicketSell();
ticketSell1.start();
ticketSell2.start();
ticketSell3.start();
}
}
class TicketSell extends Thread {
//1.获取ReentrantLock对象,如果参数为true,则每个线程的机会是公平的
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
try {
//2.打开锁
lock.lock();
if (TicketDemo.tickets > 0) {
TicketDemo.tickets--;
System.out.println(TicketDemo.tickets + "\t" + Thread.currentThread().getName());
} else {
break;
}
} finally {
//3.关闭锁
lock.unlock();
}
}
}
}
package com.lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author ym
* @create 2022-01-24 20:45
* @description
*/
public class TicketDemo1 {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread);
Thread thread2 = new Thread(myThread);
Thread thread3 = new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
}
}
class MyThread implements Runnable {
public int tickets = 100;
// public Object obj = new Object();
public ReentrantLock lock = new ReentrantLock();
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
while (true) {
try {
lock.lock();
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "\t" + tickets);
tickets--;
} else {
break;
}
} finally {
lock.unlock();
}
}
}
// public synchronized void show() {
//
// }
}
1.lock是显式锁,需要手动开启和关闭锁,synchronized是隐式锁,出了作用域自动释放
2.lock只有代码块锁,synchronized有代码块锁和方法锁
3.lock锁可以使JVM更快地调度线程,性能更好
常用:wait() notify() notifuAll()
注意:
1.这三个方法需要在同步方法或者同步代码块里调用
2.这三个方法的调用者是同步监视器
3.这三个方法定义在Object类中
1.两个方法的声明位置不同,一个在Object类,一个在Thread类
2.两个方法的调用要求不同,wait()只能在同步代码块或者同步方法调用,sleep()可以在任何场景调用
3.sleep()不会释放同步监视器,wait()会
package com.produce_and_consume;
/**
* @author ym
* @create 2022-01-25 17:59
* @description 生产者消费者模型,店员随时判断,如果超过20个货物,让生产者暂停,如果少于0个货物,让生产者工作,消费者暂停
*/
public class ClerkTest {
public static void main(String[] args) {
Clerk clerk = new Clerk();
Producer producer = new Producer(clerk);
Thread produce = new Thread(producer);
produce.start();
Consumer consumer = new Consumer(clerk);
Thread consume = new Thread(consumer);
consume.start();
}
}
class Clerk {
//货物 初始数量为0
public int goods = 0;
/**
* 生产者进行生产,需注意:
* 1.如果生产超过1个货物,就开始提醒消费者开始消费
* 2.如果少于20个货物,就开始生产
* 3.如果多于20个货物,就暂停生产
*/
public synchronized void produce() {
if (goods < 20) {
goods++;
System.out.println(Thread.currentThread().getName() + "开始生产第" + goods + "个商品");
notify();
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 消费者进行消费,需注意:
* 1.如果消费超过1个货物,就开始提醒生产者进行生产
* 2.如果多于1个货物,就开始消费
* 3.如果少于1个货物,就暂停消费
*/
public synchronized void consume() {
if (goods > 0) {
System.out.println(Thread.currentThread().getName() + "开始消费第" + goods + "个货物");
goods--;
notify();
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer implements Runnable {
private Clerk clerk;
public Producer(Clerk clerk) {
this.clerk = clerk;
}
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
System.out.println("生产者开始生产产品");
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.produce();
}
}
}
class Consumer implements Runnable {
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
System.out.println("消费者开始消费产品");
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.consume();
}
}
}
package com.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author ym
* @create 2022-01-25 19:31
* @description 使用callable方法创建线程 目的是打印100以内所有偶数的和
*/
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadTest threadTest = new ThreadTest();
FutureTask<Integer> integerFutureTask = new FutureTask<Integer>(threadTest);
Thread thread = new Thread(integerFutureTask);
thread.start();
Integer integer = integerFutureTask.get();
System.out.println(integer);
}
}
class ThreadTest implements Callable {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
@Override
public Object call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
sum += i;
}
}
return sum;
}
}
package com.ThreadPool;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author ym
* @create 2022-01-25 19:54
* @description
*/
public class ThreadPool {
public static void main(String[] args) {
//1.创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
//4.设置线程池属性
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
threadPoolExecutor.setCorePoolSize(15);
//2.使用线程池
executorService.execute(new Thread1());
executorService.submit(new Thread2());
//3.关闭线程池
executorService.shutdown();
}
}
class Thread1 implements Runnable {
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
class Thread2 implements Callable {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
@Override
public Object call() throws Exception {
for (int i = 10; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
return null;
}
}