Java 多线程(抢CPU)
哈哈哈
什么是多线程:可以让程序同时做多件事情。
多线程的作用:提高效率。
多线程的应用场景:想让多个事情同时运行。
并发(多个指令在单个CPU交替执行)和并行(多个指令在多个CPU交替执行)
多线程的实现方式:
1.继承Thread类的方式实现(简单,扩展性差)
public class ss {
public static void main(String[] args) {
//1.自己定义一个类继承Thread
//2.重写run方法
//3.创建子类的对象,并启动线程
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.setName("1");
t2.setName("2");
t1.start();
t2.start();
}
}
public class MyThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"hello");
}
}
}
2.实现Runnable接口的方式进行实现(复杂,扩展性强)
public class ss {
public static void main(String[] args) {
//1.自己定义一个类实现Runnable接口
//2.重写里面的run方法
//3.创建自己的类的对象
//4.创建一个Thread类的对象,并开启线程
MyRun mr=new MyRun();
Thread t=new Thread(mr);
Thread t2=new Thread(mr);
t.setName("1");
t2.setName("2");
t.start();
t2.start();
}
}
public class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Thread t=Thread.currentThread();
System.out.println(t.getName()+"hello");
}
}
}
3.利用Callable接口和Future接口方式实现(可以获取结果)
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class ss {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1.创建一个类MyCallable实现Callable接口
//2.重写call
//3.创建MyCallable对象
//4.创建FutureTask的对象
//5.创建Thread类对象并启动
MyCallable mc=new MyCallable();
FutureTask<Integer> ft=new FutureTask<>(mc);
Thread t1=new Thread(ft);
t1.start();
Integer result=ft.get();
System.out.println(result);
}
}
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception{
int sum=0;
for (int i = 0; i < 100; i++) {
sum=sum+i;
}
return sum;
}
}
多线程的常用成员方法
public class ss {
public static void main(String[] args) throws InterruptedException {
//getName
MyThread mt=new MyThread("111");
MyThread t2=new MyThread();
mt.start();
t2.start();
//setName
//....
//currentThread
Thread t=Thread.currentThread();
System.out.println(t.getName());
//sleep(long time)毫秒 睡眠时间
System.out.println("11111");
Thread.sleep(5000);
System.out.println("22222");
}
}
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(getName()+"@"+i);
}
}
}
线程的优先级
public class ss {
public static void main(String[] args) throws InterruptedException {
MyRunnable mr=new MyRunnable();
Thread t1=new Thread(mr,"1");
Thread t2=new Thread(mr,"2");
System.out.println(t1.getPriority());//默认优先级5
System.out.println(t2.getPriority());//默认优先级5//最小1//最大10
t1.setPriority(1);
t2.setPriority(10);
t1.start();
t2.start();
}
}
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"@"+i);
}
}
}
守护线程(起码有2个线程)
public class ss {
public static void main(String[] args) throws InterruptedException {
MyThread t1=new MyThread();
MyThread2 t2=new MyThread2();
t1.setName("1");
t2.setName("2");
t2.setDaemon(true);
t1.start();
t2.start();
}
}
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName()+"@"+i);
}
}
}
public class MyThread2 extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName()+"@"+i);
}
}
}
礼让线程
public class ss {
public static void main(String[] args) throws InterruptedException {
MyThread2 t1=new MyThread2();
MyThread2 t2=new MyThread2();
t1.setName("1");
t2.setName("2");
t1.start();
t2.start();
}
}
public class MyThread2 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"@"+i);
Thread.yield();//礼让一下,再重新抢夺CPU的执行权
}
}
}
插入线程/插队线程
public class ss {
public static void main(String[] args) throws InterruptedException {
MyThread t1=new MyThread();
t1.setName("1");
t1.start();
t1.join();//把t线程插入到当前线程(main)之前
for (int i = 0; i < 10; i++) {
System.out.println("main"+i);
}
}
}
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"@"+i);
}
}
}
线程的生命周期:
一个线程从创建,到结束。
线程的安全问题
(下面这个代码存在问题)
public class ss {
public static void main(String[] args) throws InterruptedException {
MyThread t1=new MyThread();
MyThread t2=new MyThread();
MyThread t3=new MyThread();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
public class MyThread extends Thread{
static int ticket=0;//这个类所有对象共享ticket数据(加了static)
@Override
public void run() {
while (true){
if(ticket<100){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
ticket++;
System.out.println(getName()+"正在卖第"+ticket+"张票");
}else break;
}
}
}
同步代码块
(可以解决问题)
public class ss {
public static void main(String[] args) throws InterruptedException {
MyThread t1=new MyThread();
MyThread t2=new MyThread();
MyThread t3=new MyThread();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
public class MyThread extends Thread{
static int ticket=0;//这个类所有对象共享ticket数据(加了static)
static Object obj=new Object();
@Override
public void run() {
while (true){
synchronized (obj){
if(ticket<100){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
ticket++;
System.out.println(getName()+"正在卖第"+ticket+"张票");
}else break;
}
}
}
}
同步方法:
就是把synchronized关键字加到方法上
public class ss {
public static void main(String[] args) throws InterruptedException {
MyRunnable mr=new MyRunnable();
Thread t1=new Thread(mr);
Thread t2=new Thread(mr);
Thread t3=new Thread(mr);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
public class MyRunnable implements Runnable{
int ticket=0;
@Override
public void run() {
while (true){
if (method()) break;
}
}
private synchronized boolean method() {
if(ticket==100){
return true;
}else{
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
ticket++;
System.out.println(Thread.currentThread().getName()+"在卖第"+ticket+"张票");
}
return false;
}
}
lock锁
死锁
等待唤醒机制
1.消费者
2.生产者
public class Test {
public static void main(String[] args) {
Cook c=new Cook();
Foodie f=new Foodie();
// c.setName("厨师");
// f.setName("吃货");
c.start();
f.start();
}
}
public class Foodie extends Thread{
@Override
public void run() {
while (true){
synchronized (Desk.lock){
if(Desk.count==0){
break;
}else{
if(Desk.foodFlag==0){
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
else{
Desk.count--;
System.out.println("吃货还能吃"+Desk.count+"碗");
Desk.lock.notifyAll();
Desk.foodFlag=0;
}
}
}
}
}
}
public class Cook extends Thread{
@Override
public void run() {
while (true){
synchronized (Desk.lock){
if(Desk.count==0){
break;
}else {
if (Desk.foodFlag==1){
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else {
System.out.println("厨师做了一碗面条");
Desk.foodFlag=1;
Desk.lock.notifyAll();
}
}
}
}
}
}
public class Desk {
public static int foodFlag=0;//桌上是否有食物
public static int count=10;
public static Object lock=new Object();
}
利用阻塞队列方式实现
import java.util.concurrent.ArrayBlockingQueue;
public class Test {
public static void main(String[] args) {
ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(1);
Cook c=new Cook(queue);
Foodie f=new Foodie(queue);
c.start();
f.start();
}
}
import java.util.concurrent.ArrayBlockingQueue;
public class Foodie extends Thread{
ArrayBlockingQueue<String> queue;
public Foodie(ArrayBlockingQueue<String>queue){
this.queue=queue;
}
@Override
public void run() {
while (true){
try {
String food=queue.take();
System.out.println(food);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Desk {
public static int foodFlag=0;//桌上是否有食物
public static int count=10;
public static Object lock=new Object();
}
import java.util.concurrent.ArrayBlockingQueue;
public class Cook extends Thread{
ArrayBlockingQueue<String> queue;
public Cook(ArrayBlockingQueue<String>queue){
this.queue=queue;
}
@Override
public void run() {
while (true){
try {
queue.put("面条");
System.out.println("厨师做了一碗面条");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
多线程的6种状态
线程池:
1.创建线程池
2.提交任务
3.所有任务全部执行完毕,关闭线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class n {
public static void main(String[] args) {
// 1.获取线程池对象
// ExecutorService pool1=Executors.newCachedThreadPool();//无上限
ExecutorService pool1=Executors.newFixedThreadPool(3);//有上限
// 2.提交任务
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
// 3.销毁线程池
pool1.shutdown();
}
}
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
自定义线程池
回头再看
最大并行数
4核8线程:最大并行数8
public class sa {
public static void main(String[] args) {
int count=Runtime.getRuntime().availableProcessors();
System.out.println(count);
}
}
线程池多大合适
CPU密集型运算 最大并行数+1
I/O密集型运算 最大并行数*期望CPU利用率*(总时间(CPU计算时间+等待时间)/CPU计算时间)
多线程的额外扩展内容
回头再看