进程
线程
死锁
进程: 进程就是程序的执行过程。进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元
进程特点:动态 并发 独立
1、线程:
进程内部的一个执行单元
独立调度和分派的基本单位
共享进程资源
2、 继承Thread类的线程
在thread中的run方法中写实现的功能,比如System.out.println(“我是一个线程”);
在test中建立Thread,开启(必须调用Start)Thread();
方式一:
最简单的用法:
package com.xiancheng;
public class MyThread extends Thread{
public void run() {
System.out.println("我是一个线程");
}
}
package com.xiancheng;
public class Test {
public static void main(String[] args) {
//
MyThread t=new MyThread();
System.out.println("线程开始执行");
t.start();
System.out.println("线程运行结束");
}
}
方式2:
public class MyThread extends Thread{
public MyThread(){
}
public MyThread(String name){
super(name);
}
private int ticket=200;
public void run(){
while(ticket>0){
System.out.println(getName()+"卖出了"+ticket-- +"票");
//注意书写方式getname
}
}
}
MyThread t1=new MyThread("售票员一");
MyThread t2=new MyThread("售票员二");
MyThread t3=new MyThread("售票员三");
MyThread t4=new MyThread("售票员四");
t1.start();
t2.start();
t3.start();
t4.start();
3、 继承Runnable类的线程
使用方式:
1、创建继承于Runnable类的线程类
public class 线程名 implements Runnable(){
}
2、在test文件中调用时:
方式一:线程类名 对象=new 线程类名();
方式二、Thread t=new Thread (new 线程名());
实例:甲乙两人去现金,现金不够100时不能取出
package com.xiancheng;
import java.security.GeneralSecurityException;
public class Demo implements Runnable{
private int sum=1005;
private String e="abd";//锁
@Override
public void run() {
// TODO Auto-generated method stub
while(sum>100){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (e) {
if(sum>100){
System.out.println(Thread.currentThread().getName()+"提出100元");
sum=sum-100;
}
}
}
System.out.println(sum);
}
}
package com.xiancheng;
public class Demotast {
public static void main(String[] args) {
Demo runnable=new Demo();
Thread t1=new Thread(runnable,"甲");
//=Thread t1=new Thread(new Runnable("甲"));
Thread t2=new Thread(runnable,"乙");
t1.start();
t2.start();
}
}
死锁:它是操作系统或软件运行的一种状态:在多任务系统下,当一个或多个进程等待系统资源,而资源又被进程本身或其它进程占用时,就形成了死锁。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象
实例:
thread1与thread2互相申请lock1与lock2,形成相互资源申请不到,导致死锁。
package com.xiancheng;
public class Threaone implements Runnable{
String lock1="abc";
String lock2="bef";
@Override
public void run() {
//注意lock2 的申请必须在lock1的try/catch内部
//synchronized (lock1) {}的一个完整的{}之后lock1才能释放
synchronized (lock1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("lock2");
synchronized (lock2) {
}
}
}
}
package com.xiancheng;
public class Threadtwo implements Runnable {
String lock1="abc";
String lock2="bef";
public void run() {
synchronized (lock2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("lock1");
synchronized (lock1) {
}
}
}
}
package com.xiancheng;
public class Testlock {
public static void main(String[] args) {
// TODO Auto-generated method stub
Threaone run1=new Threaone();
Threadtwo run2=new Threadtwo();
Thread t1=new Thread(run1,"甲");
Thread t2=new Thread(run2,"乙");
t1.start();
t2.start();
}
}
可以看到线程运行死锁。
死锁的解锁:死锁的解锁是通过调用锁.wait()和锁.notify()实现的。
例如:lock.wait(); 释放锁
lock.notify(); 唤醒线程
解锁例子:
public class Threaone implements Runnable{
String lock1="abc";
String lock2="bef";
@Override
public void run() {
//注意把锁放到锁中才能死锁,相当一个人需要在有了一把锁还需要有一把锁才能完成任务,
//即lock1的释放必须完成synchronized (lock1) {得到lock2}所有内容才能释放lock1
//如果不放到锁中,相当于用完lock1 就释放了
//即synchronized (lock1) {}释放lock1,得到lock2,synchronized (lock2) {}释放lock2
synchronized (lock1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("等待lock2");
try {
System.out.println("释放lock1");
lock1.wait();//线程进入等待状态,并释放lock1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("唤醒lock2线程");
}
}
System.out.println("thread1完成");
}
}
public class Threadtwo implements Runnable {
String lock1="abc";
String lock2="bef";
public void run() {
synchronized (lock2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("lock1");
synchronized (lock1) {
System.out.println("等到了lock1");
lock1.notify();//唤醒等待lock2 的线程
System.out.println("唤醒线程");
}
}
System.out.println("thread2完成");
}
}
public class Testlock {
public static void main(String[] args) {
// TODO Auto-generated method stub
Threaone run1=new Threaone();
Threadtwo run2=new Threadtwo();
Thread t1=new Thread(run1,"甲");
Thread t2=new Thread(run2,"乙");
t1.start();
t2.start();
}
}
可以看到解锁后线程1、2都执行完成