多线程:
1、多线程的概述
进程和线程:
进程想要执行任务就需要依赖线程,一个进程运行时产生了多个线程
2、线程生命周期
3、创建线程的方法(三种)
创建方式1:
子类Thread。在Thread类自身实现Runnable,但其run方法不起作用。应用程序可以子类Thread提供自己的实现run。
//创建线程方式1:直接继承Thread类
public class TestThread extends Thread{
@Override
public void run() {
// Thread.currentThread().setName("我是子线程");
for (int i = 0; i <1000; i++) {
System.out.println("我是子线程"+i);
}
}
public static void main(String[] args) {
TestThread tt = new TestThread();
tt.start();
for (int i = 0; i < 200; i++) {
System.out.println("哈哈哈我是主线程"+i);
}
创建方式二:
提供一个Runnable对象。该 Runnable接口定义了一个方法,run用于包含在线程中执行的代码。该Runnable对象将传递给Thread构造函数。
public class ThreadRunnnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println("lalala我是子线程"+i);
}
}
public static void main(String[] args) {
ThreadRunnnable tr = new ThreadRunnnable();
Thread thread = new Thread(tr);
thread.start();
for (int i = 0; i < 500; i++) {
System.out.println("主线程"+i);
}
}
}
创建方式三:
实现Callable接口,可以有返回值
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class HelloCallable implements Callable {
int i = 0;
@Override
public Object call() throws Exception {
for (int i1 = 0; i1 < 10; i1++) {
System.out.println(Thread.currentThread().getName() + ":" + i++);
}
return i;
}
public static void main(String[] args) {
HelloCallable helloCallable = new HelloCallable();
for (int i = 0; i < 10; i++) {
FutureTask futureTask = new FutureTask(helloCallable);
Thread thread = new Thread(futureTask, "子线程" + i);
thread.start();
try {
System.out.println("子线程" + i + "返回值:" + futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
线程命名:
//线程的命名
//1.实例化一个线程对象
Thread t = new Thread();
t.setName("custom");
//输出看看是否有没有实现命名
System.out.println(t.getName());
//2.实例化一个对象的同时,通过构造方法对线程命名。这个用于实现Runnable接口的类方便
Thread t1=new Thread(()->{},"hahha");
System.out.println(t1.getName());
//3.类继承Thread,实例化线程对象的同时进行名称的赋值,利用的构造方法
MyThread m = new MyThread("xixi");
System.out.println(m.getName());
}
}
class MyThread extends Thread{
public MyThread(){}
public MyThread(String name){
//super(name);
this.setName(name);
}
}
4、线程的状态管理
线程优先级
“高优先级线程”被分配CPU的概率高于“低优先级线程”。只能说提高了概率
public class ThreadPriority implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("线程名称:"
+ Thread.currentThread().getName()
+ ",线程优先级:"
+ Thread.currentThread().getPriority()
+ ",循环:" + i);
}
}
public static void main(String[] args) {
ThreadPriority threadPriority = new ThreadPriority();
Thread thread1 = new Thread(threadPriority);
thread1.setName("线程1");
thread1.setPriority(Thread.MIN_PRIORITY);
Thread thread2 = new Thread(threadPriority);
thread2.setName("线程2");
thread2.setPriority(Thread.MAX_PRIORITY);
thread1.start();
thread2.start();
}
}
线程休眠:sleep方法
Thread.sleep使当前线程在指定时间段内暂停执行
public class ThreadSleep implements Runnable {
@Override
public void run() {
String info[] = {
"春眠不觉晓",
"处处闻啼鸟",
"夜来风雨声",
"花落知多少"
};
for (int i = 0; i < info.length; i++) {
System.out.println(info[i]);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadSleep threadSleep = new ThreadSleep();
Thread thread = new Thread(threadSleep);
thread.start();
}
}
线程礼让:yield方法
Thread类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态下的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。
public class ThreadYield implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始了");
Thread.yield();
System.out.println(Thread.currentThread().getName() + "结束了");
}
public static void main(String[] args) {
ThreadYield threadYield = new ThreadYield();
Thread thread1 = new Thread(threadYield, "线程1");
Thread thread2 = new Thread(threadYield, "线程2");
thread1.start();
thread2.start();
}
}
线程联合:join方法
join方法允许一个线程等待另一线程的完成。
public class ThreadJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("子线程" + i);
}
}
public static void main(String[] args) {
ThreadJoin threadJoin = new ThreadJoin();
Thread thread = new Thread(threadJoin);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程main" + i);
if(i == 90) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
线程停止
使用标识符进行退出
public class ThreadStop implements Runnable {
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag) {
System.out.println("子线程" + i++);
}
}
public void stop() {
this.flag = false;
}
public static void main(String[] args) {
ThreadStop threadStop = new ThreadStop();
Thread thread = new Thread(threadStop);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程main" + i);
if (i == 90) {
threadStop.stop();
System.out.println("子线程停止了");
}
}
}
}
守护线程:
public class ThreadDaemon {
public static void main(String[] args) {
Daemon daemon = new Daemon();
Thread thread1 = new Thread(daemon);
thread1.setDaemon(true);
thread1.start();
Me me = new Me();
Thread thread2 = new Thread(me);
thread2.start();
}
}
public class ThreadDaemon {
public static void main(String[] args) {
Daemon daemon = new Daemon();
Thread thread1 = new Thread(daemon);
thread1.setDaemon(true);
thread1.start();
Me me = new Me();
Thread thread2 = new Thread(me);
thread2.start();
}
}
5、线程同步和锁
Java编程语言提供了两种基本的同步习惯用法:同步语句(synchronized statements )和同步方法(synchronized methods )
同步语句:
public class SynchronizedStatements implements Runnable {
public static int ticket = 100;
@Override
public void run() {
while (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized ("") {
if (ticket <= 0) {
return;
}
System.out.println(Thread.currentThread().getName()
+ "卖了1张票,剩余" + --ticket + "张票");
}
}
}
public static void main(String[] args) {
SynchronizedStatements synchronizedStatements
= new SynchronizedStatements();
Thread thread1 = new Thread(synchronizedStatements, "售票员1");
thread1.start();
Thread thread2 = new Thread(synchronizedStatements, "售票员2");
thread2.start();
Thread thread3 = new Thread(synchronizedStatements, "售票员3");
thread3.start();
}
}
同步方法:
要使同步方法,只需将synchronized关键字添加到其声明中。
public class SynchronizedMethods implements Runnable {
public static int ticket = 100;
@Override
public void run() {
sellTicket();
}
public synchronized void sellTicket() {
while (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "卖了1张票,剩余" + --ticket + "张票");
}
}
public static void main(String[] args) {
SynchronizedMethods synchronizedMethods
= new SynchronizedMethods();
Thread thread1 = new Thread(synchronizedMethods, "售票员1");
thread1.start();
Thread thread2 = new Thread(synchronizedMethods, "售票员2");
thread2.start();
Thread thread3 = new Thread(synchronizedMethods, "售票员3");
thread3.start();
}
}
6、线程协作
多线程环境下,我们经常需要多个线程的并发和协作。这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”。
package lianxi;
import java.util.LinkedList;
//测试类:生产者消费者模式
public class Test {
public static void main(String[] args) {
LinkedList<Product> list = new LinkedList<>();
Pool pool = new Pool(list, 6);
Producer producer = new Producer(pool);
producer.start();
Consumer consumer = new Consumer(pool);
consumer.start();
}
}
//产品类
class Product {
//产品名字
private String name;
//构造方法对属性进行初始化
public Product(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//缓冲区
class Pool {
//装产品的容器
LinkedList<Product> list;
int Maxsize;//容量大小
public Pool(LinkedList<Product> list, int Maxsize) {
this.list = list;
this.Maxsize = Maxsize;
}
//生产者放产品(同步方法)
public synchronized void push(Product product) {
//先判断容器是否满了,没满就等待消费者消费
if (list.size() == Maxsize) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//没满就通知生产继续放
list.add(product);
// System.out.println("生产者放了一件产品,产品名字为"+product.getName());
this.notify();
}
//消费者拿产品
public synchronized Product pop() {
//先判断产品池是否空了,空了就等待生产者生产
if (list.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Product pro = list.remove(0);
//没空 就通知消费者消费
this.notify();
// System.out.println("消费者拿了一件产品,产品名字为"+pro.getName());
return pro;
}
}
//生产者生产
class Producer extends Thread {
Pool pool;
public Producer(Pool pool) {
this.pool = pool;
}
@Override
public void run() {
// int i=0;可以和while(true),i++ 一起使用
for (int i1 = 1; i1 < 10; i1++) {
Product p = new Product("牙膏"+i1);
this.pool.push(p);
System.out.println("生产了一件" + p.getName());
}
}
}
//消费者消费
class Consumer extends Thread {
Pool pool;
public Consumer(Pool pool) {
this.pool = pool;
}
@Override
public void run() {
// int i=0;
for (int i1 = 1; i1 < 10; i1++) {
Product pop = this.pool.pop();
System.out.println("消费了一件" + pop.getName());
}
}
}
7、线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new ThreadPool());
executorService.execute(new ThreadPool());
executorService.execute(new ThreadPool());
executorService.shutdown();
}
}
由于笔者知识范围有限,还有很多不足,欢迎大家提出宝贵的意见和进行补充,后期有新的领悟,也会继续补充!