1.进程和线程
进程:完整的程序功能
线程:进程的执行单元
进程是对线程的一个封装,一个进程至少应该有一个线程
同时:进程是具有同时性(时间片轮转),线程也具有同时性
本质上就是线程的同时性
进程把线程封装了,进程之间不能资源共享
线程是可以资源共享的
JVM起进程:多线程,执行main/GC(守护线程)
2.多线程—工人模型
每一个工人————-线程(Thread)
工人任务—————-Runnable/Thread run()
工人执行任务———-启动多线程
package thread_1;
/**
* 工人模型
* 工人--线程
* 任务
* 工人开始执行任务--线程启动
* @author Administrator
*
*/
public class Thread_1 {
public static void main(String[] args) {
Task task = new Task();//任务就是Runnable--run()
Thread w1 = new Thread(task);//Thread就是一个工人
w1.setName("doudou");
Thread w2 = new Thread(task);
w2.setName("feifei");
w1.start();//启动任务 --Thread--start()
w2.start();
}
}
/*class Worker extends Thread{//工人
}*/
class Task implements Runnable{//任务
@Override
public void run() {
/*while(true) {*/
System.out.println(Thread.currentThread()+"任务");//当前线程
/*}*/
}
}
package thread_1;
/**
* 1.Tread本身实现Runnable接口,自己可以设定任务run()
* 2.线程启动:start(),run()叫做方法调用而不是实现多线程
* 3.中断线程:flag
* 4.CPU的控制权希望可以控制一下:让出CPU
* @author Administrator
*
*/
public class Thread_2 {
public static void main(String[] args) throws InterruptedException {
DD dd = new DD();
FF ff = new FF();
dd.start();
Thread.sleep(1000);//当前线程休眠:让出CPU
ff.start();
Thread.sleep(1000);
/*dd.stop();*/
//dd.interrupt();
dd.shutUp();//手动中断线程
ff.shutUp();
/*dd.run();//真正的方法调用
ff.run();*/
}
}
class DD extends Thread{
private boolean flag =true;
@Override
public void run() {
while(flag) {
System.out.println("我有车");
}
}
public void shutUp() {
this.flag = false;
}
}
class FF extends Thread{
private boolean flag =true;
@Override
public void run() {
while(flag) {
System.out.println("我有房");
}
}
public void shutUp() {
this.flag = false;
}
}
package thread_1;
/**
* 启动一个线程计算1-1000的和
* 结果在main主线程中打印
* @author Administrator
*
*/
public class Thread_3 {
public static void main(String[] args) throws InterruptedException {
Task1 t1 = new Task1();
Thread t = new Thread(t1);
t.start();
/*Thread.sleep(1000);*/
//t.join();//等待t终止
t.yield();//暂停当前线程
System.out.println(t1.getSum());
}
}
class Task1 implements Runnable{
private int sum;
public int getSum() {
return sum;
}
@Override
public void run() {
for(int i = 0;i < 1001;i++) {
this.sum += i;
}
}
}
package thread_1;
/**
* 抛出InterruputedException异常
* 线程1 sleep
* 线程2 打扰线程1
* @author Administrator
*
*/
public class Thread_4 {
public static void main(String[] args) {
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2(t1);
t1.start();
t2.start();
}
}
class MyThread1 extends Thread{
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("被打扰");
e.printStackTrace();
}
}
}
class MyThread2 extends Thread{
private MyThread1 t1;
public MyThread2(MyThread1 t1) {
super();
this.t1 = t1;
}
@Override
public void run() {
System.out.println("中断线程");
t1.interrupt();
}
}
3.线程的状态(生命周期)
New Thread():线程被创建
线程可运行状态:抢到CPU才是真正的运行状态
运行过程中CPU被抢,阻塞,休眠sleep()/wait()
结束—–线程自动运行完/推荐:标志位
4.线程的常用方法
Start():才能开始多线程
Stop():终止线程,但不推荐
Interrupt():打断线程的状态,线程受阻,不能真正中断线程
Sleep():当前线程休眠,让出CPU,不让出锁
Join():等待线程中止
Yield():暂停当前线程
setPriority():设置线程的优先级别
setName():设置线程的名字
isAlive():测试线程是否为活动状态
线程通信
wait()
notify()
notifyAll()
5.线程同步
锁:每个对象都有一个锁,而且每个锁都只有唯一一把钥匙
保护资源,一把锁只有一把钥匙,只有执行完被锁住的程序块钥匙才能释放
同步:使用了同一个锁的代码块就叫实现了同步
同步块
同步方法
锁:
当前对象锁:synchronized(this)/普通同步锁
类锁(Class对象锁):synchronized(类.class)/静态同步方法锁
私有锁:室友类中的一个成员属性作为锁
锁保护谁:成员属性/静态成员属性/
锁有几种:(互斥锁)
this:当前对象的锁
类.class:当前类的Class对象的锁
成员属性
方法上加锁:锁就是this对象的锁
静态方法上加锁:锁就是Class实例对象的锁
锁属于谁:
锁是属于对象的
每一个对象都有唯一的锁
package thread_2;
public class LockTest {
public static void main(String[] args) {
final Method m = new Method();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m.m1();//拿到this锁
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m.m2();//m2需要this锁
}
});
t1.start();
t2.start();
}
}
/**
* m1和m2加锁,加的是this,使用同一把锁
* @author Administrator
*
*/
class Method{
private String lock = "";//lock本身是一个对象,只要是对象就有锁
public void m1() {
synchronized (lock) {//加锁
for(int i = 0 ;i < 5; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
public void m2() {
synchronized (lock) {
for(int i = 0 ;i < 5; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
}
package thread_2;
public class TicketTest {
public static void main(String[] args) {
SaleTask sal = new SaleTask();
Thread t1 = new Thread(sal);
t1.setName("网上");
Thread t2 = new Thread(sal);
t1.setName("电话");
Thread t3 = new Thread(sal);
t1.setName("现场");
t1.start();
t2.start();
t3.start();
}
}
class SaleTask implements Runnable{
int id = 100;//t1,t2,t3共同使用id这个变量
@Override
public void run() {
while(true) {
synchronized (this) {//加锁:钥匙只有一把 拿到钥匙
if(id>0) {//t1(1),t2(1),t3(1)
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("卖票:"+id--);
}else {
System.out.println("票卖完");
break;
}
}//拿到钥匙后只有执行到这里钥匙才能归还
}
}
}
锁的使用
package thread_2;
public class ReadProject {
public static void main(String[] args) throws InterruptedException {
Method1 m = new Method1();//任务类
Thread t1 = new Thread(m);
t1.start();
m.m2("主线程2");
Thread.sleep(1000);
m.m1("主线程1");
//m.m1("主线程1");
//start()--主线程1 m1----主线程2 m2 --子线程m1
//t1.start.run m1(m)
//main m1(m)
//main m2(m)
}
}
class Method1 implements Runnable{
public int b = 100;
public synchronized void m1(String name) throws InterruptedException {
System.out.println("进入m1");
Thread.sleep(1000);
System.out.println("m1:"+b+":"+name);
}
public /*synchronized*/ void m2(String name) throws InterruptedException {
b = 200;
System.out.println("进入m2");
Thread.sleep(1000);
System.out.println("m2:"+b+":"+name);
}
@Override
public void run() {
System.out.println("进入子线程");
try {
m1("子线程");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
死锁
相互等待对方占用的资源(锁)
package thread_2;
public class DeadLockTest {
public static void main(String[] args) {
DeadLock t1 = new DeadLock(0);
DeadLock t2 = new DeadLock(1);
t1.start();
t2.start();
}
}
class DeadLock extends Thread{
//一定是static才能形成死锁,如果没有static就是两个对象,不会形成死锁
private static String lock1 = new String();
private static String lock2 = new String();
private int flag;
public DeadLock(int flag) {
this.flag = flag;
}
@Override
public void run() {
if(flag == 0) {
synchronized (lock1) {//t1
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (lock2) {
}
}
}else if(flag == 1) {
synchronized (lock2) {//t2
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (lock1) {
}
}
}
}
}
6.线程通信
线程之间的资源共享
生产者-消费者模型
package thread_2;
public class Test {
public static void main(String[] args) {
Resouce r = new Resouce();
Procedure p = new Procedure(r);
Consummer c = new Consummer(r);
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(c);
Thread t4 = new Thread(c);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Mantou{
int id;
}
class Resouce{
Mantou[] arrMantou = new Mantou[6];
int index = 0;
public synchronized void push(Mantou mantou) throws InterruptedException {
if(index == arrMantou.length) {
//放满了:暂停生产,赶紧消费
System.out.println("---暂停生产---");
this.wait();//当前线程任务暂停
this.notifyAll();//通知赶紧消费
}else {
Thread.sleep(100);
arrMantou[index] = mantou;
System.out.println("放入:"+(index+1));
index++;
}
}
public synchronized Mantou pop() throws InterruptedException {
if(index == 0) {
//取完了:暂停消费,赶紧生产
System.out.println("---暂停消费---");
this.wait();
this.notifyAll();
}else {
System.out.println("取出:"+index);
Thread.sleep(100);
index--;
}
return arrMantou[index];
}
}
class Procedure implements Runnable{
private Resouce resource;
public Procedure(Resouce resource) {
this.resource = resource;
}
@Override
public void run() {
while(true) {
Mantou mantou = new Mantou();
try {
resource.push(mantou);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Consummer implements Runnable{
private Resouce resource;
public Consummer(Resouce resource) {
this.resource = resource;
}
@Override
public void run() {
while(true) {
try {
Mantou mantou = resource.pop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
7.线程池
线程池中有很多存在的线程
好处:节约时间,管理线程,简化工作量
package thread_3;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
public static void main(String[] args) {
//执行单个线程的线程池
//ExecutorService pool = Executors.newSingleThreadExecutor();
//执行固定线程的线程池
//ExecutorService pool = Executors.newFixedThreadPool(2);
//可以新建线程的线程池
/*ExecutorService pool = Executors.newCachedThreadPool();
MyTask task1 = new MyTask();//runnable,run
MyTask task2 = new MyTask();
MyTask task3 = new MyTask();
MyTask task4 = new MyTask();
MyTask task5 = new MyTask();
pool.execute(task1);//任务交给线程池执行
pool.execute(task2);
pool.execute(task3);
pool.execute(task4);
pool.execute(task5);
pool.shutdown();*/
//实现调度的线程池
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"*******");
}
}, 1000, 5000, TimeUnit.MICROSECONDS);
pool.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"------------");
}
}, 1000, 3000, TimeUnit.MICROSECONDS);
}
}
模拟线程池
1.ThreadPool:线程池 List<Thread>
2.ThreadTask: 执行任务的线程
3.Task:任务 abstract
4.TaskQueue:任务队列
请关注“知了堂学习社区”,地址:http://www.zhiliaotang.com/portal.php