线程与线程池

线程与线程池

进程是什么?
进程:正在运行的程序,进程是CPU分配的最小单元
线程是什么?
线程:线程是进程中的一个执行单元,线程是CPU调度的最小单元
一个进程中至少有一个线程,也就是主线程(mainThread),也可以
添加其他子程序!线程之间各自执行,互不干扰!
多线程开发:就是在程序中创建多条线程开发程序!

线程与死锁

两种创建子线程的方式:

  1. Thread类
    a.创建类并且继承于Thread
    b.重写run方法
    c.把需要放在子线程中操作的代码放在run方法中
    d.创建对象,调用start方法

  2. Runable 接口
    a.创建类并且实现Runable接口
    b.重写run方法
    c.把需要放在子线程中操作的代码放在run方法中
    d.创建Thread对象,把之前创建的类作为Thread构造方法的参数
    e.Thread对象 调用start方法

方式一

创建类并继承Thread

package com.thread;

public class MyThread extends Thread {
	
	public void run() {
		//注意注意!!需要放在子线程中实现的方法 请写这里
		System.out.println(Thread.currentThread().getName());
		System.out.println("这是MyThread");
	}
}

创建对象,调用start方法

package com.thread;

public class ThreadTest {

	public static void main(String[] args) {
//		int a=10;
//		System.out.println(Thread.currentThread().getName());//获得线程的名字	 
		//方式1
		MyThread myThread=new MyThread();
//		myThread.run(); main主线程执行
		myThread.start();//子线程执行
		}
	}
方式二

创建类并且实现Runable接口

package com.thread;

public class MyRunable implements Runnable {

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName());
		System.out.println("这里是MyRunable");
	}
}

创建对象,调用start方法

package com.thread;

public class ThreadTest {

	public static void main(String[] args) {
		//方式2
		MyRunable myRunable=new MyRunable();
		Thread thread=new Thread(myRunable);
		thread.start();
		}
	}
方式三

匿名内部类的写法 缺点:只会走一次啦

package com.thread;
public class ThreadTest {
	public static void main(String[] args) {
Thread thread2=new Thread() {
			@Override
			public void run() {
				System.out.println("这是第三(1)种写法"+Thread.currentThread().getName());
			}
		};
		thread2.start();
		//===========
		new Thread() {
			@Override
			public void run() {
				System.out.println("这是第三(2)种写法"+Thread.currentThread().getName());
			}
		}.start();
		
		}	
	}
方式四

Runable的匿名类写法

package com.thread;
public class ThreadTest {
	public static void main(String[] args) {
		Runnable runnable=new Runnable() {
			@Override
			public void run() {
				System.out.println("这是Runnable的匿名类"+Thread.currentThread().getName());
			}
		};
		Thread thread3=new Thread(runnable);
		thread3.start();
		}
	}

练习:做一个卖票的练习
分析:来个人买票,这张票其他人就不能再买了,不然容易一张票被几个人买。所以要加一个锁,死锁就是一个线程进入其他的线程进不去
创建类并且实现Runable接口中的run方法

package com.thread;

import java.util.concurrent.locks.ReentrantLock;

public class SaleTicket implements Runnable{
	//定义总票数
	int count =100;
	private ReentrantLock lock=new ReentrantLock();
	@Override
	public void run() {
		String name=Thread.currentThread().getName();
		while(true) {
			//lock() 加锁
			lock.lock();
			try {
				Thread.sleep(500);
				if(count>0) {
					count--;
					System.out.println(name+"在卖第"+(100-count)+"票");
				}else {
					break;
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally {				
				lock.unlock();//解锁
			}
		}
		
	}
}

测试:

package com.thread;
public class ThreadTest {
	public static void main(String[] args) {
		SaleTicket saleTicket=new SaleTicket();
		Thread t1=new Thread(saleTicket,"窗口1");
		Thread t2=new Thread(saleTicket,"窗口2");
		Thread t3=new Thread(saleTicket,"窗口3");

		t1.start();
		t2.start();
		t3.start();
	}

}

线程池

适用场景:单个任务时间短,但数量庞大
线程池:对线程的管理,合理的使用
特点:只管往线程池里添加任务即可,线程池会按照自身特点分配线程

一.缓存线程池

缓存线程池:无限大,当执行后面任务的时候,如果前面的任务
已经执行完毕,线程是可以复用,不是每个任务都会对应的创建线程。

package com.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
	public static void main(String[] args) {
	ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
		for (int i = 0; i < 30; i++) {
			final int index=i;
			cachedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					//需要放在子线程中执行的代码
					System.out.println(index);
					System.out.println(Thread.currentThread().getName());
				}
			});
		}
		//关闭线程池
		cachedThreadPool.shutdown();
		}
	}
二.固定线程池

固定线程池:线程池能够容纳的线程数量固定

package com.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
	public static void main(String[] args) {
	ExecutorService fixedThreadPool=Executors.newFixedThreadPool(3);
		for (int i = 0; i < 10; i++) {
			final int index=i;
			fixedThreadPool.execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(index);
					System.out.println(Thread.currentThread().getName());
				}
			});
		}
		//关闭线程池
		fixedThreadPool.shutdown();
		}
	}
三.单一线程池

单一线程池:只有一个线程 保证FIFO(先进先出)

package com.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
	public static void main(String[] args) {
	ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();
		for (int i = 0; i < 10; i++) {
			final int index=i;
			singleThreadExecutor.execute(new Runnable() {
				
				@Override
				public void run() {
					System.out.println(index);
					System.out.println(Thread.currentThread().getName());
				}
			});
		}
		//关闭线程池
		singleThreadExecutor.shutdown();
		}
	}
四.定时线程池

定时线程池:支持定时已及周期性执行
方法一

package com.pool;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadPool {

	public static void main(String[] args) {
	ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(5);
		
		//延时3秒 再执行任务	
		scheduledExecutorService.schedule(new Runnable() {
			@Override
			public void run() {
				
				System.out.println("你迟到了3秒!罚你300个俯卧撑!");
				
			}
		}, 3, TimeUnit.SECONDS);//3+i
		//第二个参数是延迟时间
		//第三个参数是时间单元(就是时 分 秒 )
	
	}

}

第二个方法

package com.pool;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadPool {

	public static void main(String[] args) {
	ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(5);
		scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("呵呵");
			}
		}, 1, 3, TimeUnit.SECONDS);
		//参数二是初次任务的延时时间
		//参数3:是从第二次开始周期循环执行的间隔时间
		}
	}

OK!线程与线程池就这么多了;有点蒙,还好以后开发中用到线程的地方,别人都写好了以后会了在来看看吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值