一、线程状态
1.线程创建
方式一:继承Thread类,实现run方法,本质Thread类还是实现了Runnable接口。Thread作为静态代理类。
//继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
//将需要完成的业务写在这里
System.out.println("线程创建:"+Thread.currentThread().getName());
}
public static void main(String[] args) {
//创建线程
MyThread my = new MyThread();
//开启线程,如果调用run方法,不会创建新线程
my.start();
// my.run();
System.out.println("程序结束");
}
}
/** 调用start方法
程序结束
线程创建:Thread-0
*/
/**
线程创建:main
程序结束
*/
方式二:实现Runnable接口,重写run方法。实际使用中推荐使用
//实现接口Runnable, 常用
public class MyThreadImpl implements Runnable {
@Override
public void run() {
System.out.println("线程创建: "+ Thread.currentThread().getName());
}
public static void main(String[] args) {
System.out.println("程序开始");
new Thread(new MyThreadImpl()).start();
System.out.println("程序结束");
}
}
/**
程序开始
程序结束
线程创建: Thread-0
*/
方式三:实现Callable接口,重写call()方法
优点:
- 定义返回值
- 抛出异常
/**
* 实现callable接口,可以获取线程返回值
*/
public class ThreadTest implements Callable<Boolean> {
private String name; //线程名字
public ThreadTest(String name){
this.name = name;
}
@Override
public Boolean call() throws Exception {
System.out.println("线程已经创建,线程名:"+name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建线程
ThreadTest t1 = new ThreadTest("1");
ThreadTest t2 = new ThreadTest("2");
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(2);
//提交线程执行
Future<Boolean> r1 = service.submit(t1);
Future<Boolean> r2 = service.submit(t2);
//获取返回结果
System.out.println("线程1返回结果:"+r1.get());
System.out.println("线程2返回结果:"+r2.get());
//关闭线程池
service.shutdown();
}
}
线程运行
调用Thread对象的start方法即可
2.修改线程名称
如果是继承Thread类,可以添加一个带String参数的构造函数,或者使用对象调用setName()方法。
//继承Thread类
public class MyThread extends Thread {
public MyThread(String name){
this.setName(name);
}
}
如果是实现的Runnable接口,可以在创建时指定第二个参数
new Thread(new MyThreadImpl(),“MyThreadImpl”).start();
3.线程的休眠
每个对象都有一把锁,sleep并不会释放锁
try {
Thread.sleep(1000); //单位是毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
4.线程的优先级
设置线程优先级意味着线程可以更大概率得到CPU时间片
//数字越大优先级越高
//Thread.MAX_PRIORITY(10) – Thread.MIN_PRIORITY(1)
my.setPriority(4);
5.线程让出当前执行权限
当前线程执行状态由运行态变为就绪态。至于是否可以让出执行权限,看CPU调度
my.yield();
6.线程停止
建议使用一个标志位来标志线程停止
一般最好让线程自己执行完毕
public class Thread1 implements Runnable {
private Boolean IsStop = false;
@Override
public void run() {
while (!IsStop){
System.out.println("线程运行");
}
}
public void SetStop(Boolean flag){
this.IsStop = flag;
System.out.println("线程停止");
}
public static void main(String[] args) throws InterruptedException {
Thread1 test = new Thread1();
Thread t1 = new Thread(test);
t1.start();
int i = 1000;
Thread.sleep(3000);
test.SetStop(true);
}
}
7.等待某个线程结束
Thread1 test = new Thread1();
Thread t1 = new Thread(test);
t1.start();
int i = 1000;
Thread.sleep(3000);
t1.join();
等待t1线程执行完毕。
一般用于main函数中等待其他线程执行结束
8.获取线程状态
线程状态枚举类
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* 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.
*/
RUNNABLE,
/**
* 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
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called {@code Object.wait()}
* on an object is waiting for another thread to call
* {@code Object.notify()} or {@code Object.notifyAll()} on
* that object. A thread that has called {@code Thread.join()}
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* 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:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
获取线程状态
Thread.State state = t1.getState();
二、线程访问资源同步
import java.util.concurrent.locks.ReentrantLock;
/**
* 同步代码
*/
public class SynchronizedStuff {
/**
* 同步方法的锁:
* 静态方法是类.class
* 非静态方法是this
*/
public synchronized static void sale(){
if (DataTest.tickets >0)
{
System.out.println("还剩:"+ DataTest.tickets-- +"张票");
}
}
public static void main(String[] args) {
//可重入锁
ReentrantLock mylock = new ReentrantLock();
Runnable t = new Runnable() {
@Override
public void run() {
while (DataTest.tickets > 0)
{
//方式一
synchronized (this){//需要同一把锁
if (DataTest.tickets >0)
{
System.out.println("还剩:"+ DataTest.tickets-- +"张票");
}
}
//方式二
// sale();
//方式三
// mylock.lock();
// if (DataTest.tickets >0)
// {
// System.out.println("还剩:"+ DataTest.tickets-- +"张票");
// }
// mylock.unlock();
}
}
};
new Thread(t,"Thread 0").start();
new Thread(t,"Thread 1").start();
new Thread(t,"Thread 2").start();
new Thread(t,"Thread 3").start();
}
}
class DataTest{
public static int tickets = 100;
}
三、线程死锁
多个线程持有对方需要的锁。相互等待造成死锁。
/**
* 死锁示例
*/
public class DeadLock {
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (a){
System.out.println("aaaa");
synchronized (b){
System.out.println("bbbbbbb");
}
}
}
}, "Thread1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (b){
System.out.println("bbbb");
synchronized (a){
System.out.println("aaaaa");
}
}
}
}, "Thread1");
Thread t3 = new Thread(() ->{
System.out.println("testllll");
}, "Thread1");
t1.start();
t2.start();
// t3.start();
}
}
解决死锁问题
/**
* 死锁示例
*/
public class DeadLock {
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (a){
System.out.println("获取A锁");
try {
a.wait(); //释放A锁并等待
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b){
System.out.println("获取A+B锁");
}
}
}
}, "Thread1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (b){
System.out.println("获取B锁");
synchronized (a){
System.out.println("获取B+A锁");
// a.notify(); //通知等待的任意一个对象A
a.notifyAll(); //通知等待的所有对象A
}
}
}
}, "Thread1");
Thread t3 = new Thread(() ->{
System.out.println("testllll");
}, "Thread1");
t1.start();
t2.start();
// t3.start();
}
}
四、生产消费模式
生产者:
队列满了之后等待
消费者:
队列没有元素等待
//产品类
public class Production {
private String name;
public Production(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
//消费者:
public class Consumer extends Thread {
private ProductPool pool;
public Consumer(ProductPool pool){
this.pool = pool;
}
@Override
public void run() {
while (true){
Production production = this.pool.pop();
System.out.println("消费了一个产品: "+production.getName());
}
}
}
//生产者:
public class Producer extends Thread {
private ProductPool pool;
public Producer(ProductPool pool){
this.pool = pool;
}
@Override
public void run() {
while (true){
String name = (int)(Math.random()*100) +"产品";
Production production = new Production(name);
this.pool.push(production);
System.out.println("生产了一个产品: "+production.getName());
}
}
}
//产品池
import java.util.LinkedList;
import java.util.List;
public class ProductPool {
private List<Production> productList;
private int maxSize = 0;
public ProductPool(int maxSize){
this.productList = new LinkedList<>();
this.maxSize = maxSize;
}
public synchronized void push(Production producttion){
if (this.productList.size() == maxSize){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.productList.add(producttion);
this.notifyAll();
}
public synchronized Production pop(){
if (this.productList.size() == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Production production = this.productList.remove(0);
this.notifyAll();
return production;
}
}
//主程序
public class Program {
public static void main(String[] args) {
//产品队列
ProductPool productPool = new ProductPool(10);
//生产者、消费者共享队列
Consumer c = new Consumer(productPool);
Producer p = new Producer(productPool);
p.start();
c.start();
}
}
五、线程池
public class ThreadTest implements Callable<Boolean> {
private String name; //线程名字
public ThreadTest(String name){
this.name = name;
}
@Override
public Boolean call() throws Exception {
System.out.println("线程已经创建,线程名:"+name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建线程
ThreadTest t1 = new ThreadTest("1");
ThreadTest t2 = new ThreadTest("2");
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(2);
//提交线程执行
Future<Boolean> r1 = service.submit(t1);
Future<Boolean> r2 = service.submit(t2);
service.execute(new MyThread());
service.execute(new MyThread());
//获取返回结果
System.out.println("线程1返回结果:"+r1.get());
System.out.println("线程2返回结果:"+r2.get());
//关闭线程池
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
Future submit(Callable task);
void execute(Runnable command);
二者接受的参数类型不一样。