进程:执行中的程序
线程:轻量级的进程
每个运行的程序都是一个进程,在一个进程中还可以有多个执行单元同时运行,这些执行单元可以看作程序执行的一条条线索,被称为线程。
线程本身不能单独运行,必须放在一个进程中才能执行。
线程的创建
单线程:
MyThread myThread = new MyThread();
myThread.run();
Class MyThread{
While(true){
Syso...
}
Public void run(){
While(true){
Syso...
}
}
}
只有run方法里面的语句执行了。。。
继承Thread类创建多线程
MyThread myThread = new MyThread();
myThread.start();
While(true){
Syso...
}
Class MyThread extends Thread{
Public void run(){
While(true){
Syso...
}
}
两个语句轮流执行
实现Runnable接口创建多线程
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
Thread.start();
While(true){
Syso...
}
Class MyThread implements Runnable{
Public void run(){
While(true){
Syso...
}
}
}
两条语句都执行了
两线程对比分析
实现Runnable接口相对于继承Thread类来说,有以下好处:
(1)适合多个相同程序代码的线程去处理同一个资源的情况,把线程同程序代码、数据有效的分离,很好地体现了面向对象的思想。
(2)可以避免由于Java的单继承带来的局限性。
线程的生命周期
线程休眠
休眠方法sleep(毫秒数)
Thread.Sleep(s);
要处理或抛出异常
线程休眠用于希望人为地控制线程,使正在执行的线程暂停。
多线程同步
问题由来:多个线程共享资源没有进行控制。
同步代码块
Synchronized(lock){
操作共享资源代码块
}
Lock是一个锁对象,它是同步代码块的关键。当线程执行同步代码块时,首先会检查锁对象的标志位,默认为1,此时线程会执行同步代码块,同时将锁对象的标志位置为0.
同步方法
Synchronized 返回值类型 方法名 (【参数,。。。。。】)
调用哪个方法给哪个方法加锁。
当线程进入同步方法的时候,会获得同步方法所属对象的锁。一旦获得对象锁,则其他线程不能再执行被锁对象的其他任何同步方法,只有在同步方法执行完毕之后释放了锁,其他线程才能执行。
多线程通信
在Object类中提供了wait()、notify()、notifyAll()方法用于解决通信问题
Wait():使当前线程放弃同步锁并进入等待,直到其他线程进入此同步锁,并调
用notify()方法,或notifyAll()方法唤醒该线程为止
Notify()唤醒此同步锁上等待的第一个调用wait()方法的线程
notifyAll()唤醒此同步锁上调用wait()方法的所有线程
例子代码:
取钱问题:
package lesson13;
public class Account {
public int money;
public Account(int money){
this.money = money;
}
public int getcash(int getmoney){
if(money<getmoney){
System.out.println("取钱失败,余额不足");
return -1;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
money -= getmoney;
return money;
}
}
package lesson13;
public class getCash extends Thread {
Account account;
public int getmoney;
public String type;
public getCash(Account account,int getmoney,String type){
this.account = account ;
this.getmoney = getmoney;
this.type = type;
}
public void run(){
int cash = account.getcash(getmoney);
if(cash>0){
System.out.println("在"+type+"取"+getmoney+"钱成功,余额为:"+cash);
}else{
System.out.println("在"+type+"取"+getmoney+"钱失败,余额不足");
}
}
}
package lesson13;
public class Test {
public static void main(String[] args) {
Account account = new Account(5000);
getCash g1 = new getCash(account,4000, "ATM");
getCash g2 = new getCash(account,3000, "柜台");
g1.start();
g2.start();
}
}
运行结果:
两个都成功
一个成功一个失败
生产者与消费者问题:
package lesson1301;
public class Phone {
public String type;
}
package lesson1301;
import java.util.ArrayList;
public class Product extends Thread {
public ArrayList<Phone> list;
public int type;
public Product(ArrayList<Phone> list){
this.list = list;
}
public void run(){
while(true){
synchronized (list) {
if(list.size()==1){
try {
list.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Phone p =new Phone();
type++;
p.type = "Phone"+type;
list.add(p);
System.out.println("生产商生产了一台"+p.type);
list.notify();
}
}
}
}
package lesson1301;
import java.util.ArrayList;
public class Customer extends Thread {
public ArrayList<Phone> list;
public Customer(ArrayList<Phone> list){
this.list = list;
}
public void run(){
while(true){
synchronized (list) {
if(list.size()==0){
try {
list.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Phone p = list.remove(0);
System.out.println("消费者消费了一台:"+p.type);
list.notify();
}
}
}
}
package lesson1301;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<Phone> list = new ArrayList<Phone>();
Product p = new Product(list);
Customer c = new Customer(list);
p.start();
c.start();
}
}
运行结果:
生产商生产了一台Phone
消费者消费了一台:Phone
。。。。。。。