程序:静态的代码
进程:程序的一次执行
线程:更小的执行单位,一个进程一般有多个线程组成,进程开启时,系统会自动开启一个主线程(main)
多任务并行时需要多线程
一 启动一个新线程
1 使用Thread的子类(重写run方法)
1.1 构造子类线程对象
1.2 调用start方法启动线程
线程启动以后就会开始执行run方法中的代码
线程的主体就是run方法
2 就使用Thread(提供实现了Runnable接口的类对象)
1.1 用Thread类来构造线程对象(但是要给构造方法提供一个实现了Runnable接口的对象,到时候线程执行的就是这个对象中的run方法)
1.2 启动线程start
二 两种方式的区别
1 java不支持多继承,第一种方式不利于对线程的进一步扩展
2 第二种方式有利于多个线程之间的数据共享
提倡使用第二种方式来创建线程
三 同步
多个线程共享数据的时候经常需要进行线程同步
1 同步代码块
//同步代码块
synchronized (this//同步对象一般就用this(共享资源))
{
需要同步的代码(一般就是访问共享资源的代码)
}
同一个同步对象标识的同步代码快,同一时间只能有一个线程在执行
2 同步方法
public synchronized void withdraw(int count)
{
需要同步的代码;
}
把同步代码快提取到一个同步方法中
多个线程之间共享数据时,即有竞争又有合作
3 生产者和消费者问题
3.1 当一个线程没办法继续执行,那么可以等待Wait
wait
3.2 如果在某个时候线程又可以继续执行,那么可以通过notify唤醒等待的线程(前提是在同一个同步对象上等待的线程)
notify
notifyAll
四 死锁
线程1 拥有同步对象A,在等待同步对象B
线程2 拥有同步对象B,在等待同步对象A
如果同步嵌套,尽量让多个线程的同步顺序相同
五 状态
中断:sleep wait join都可以被中断,中断以后会抛出中断异常
练习:
完成生产者消费者模式
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//1 线程对象
Thread thread1 = new MThread(1);
//2 线程开启
thread1.start();//run()
//1 线程对象
Thread thread2 = new MThread(2);
//2 线程开启
thread2.start();
}
}
class MThread extends Thread
{
int num = 0;
public MThread(int num)
{
this.num = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<100;i++)
System.out.print(num + " ");
}
}
public class TestRunnable {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//1 线程对象
Thread thread1 = new Thread(new Print(1));
thread1.start();
Thread thread2 = new Thread(new Print(2));
thread2.start();
}
}
class Print implements Runnable
{
private int num = 0;
public Print(int num)
{
this.num = num;
}
public void run()
{
for(int i=0;i<100;i++)
System.out.print(num + " ");
}
}
public class TestSellTicket {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SellTickets sellTickets = new SellTickets(10);
Thread thread1 = new Thread(sellTickets);
thread1.start();
Thread thread2 = new Thread(sellTickets);
thread2.start();
}
}
class SellTickets implements Runnable
{
private int tickets = 0;
public SellTickets(int tickets)
{
this.tickets = tickets;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<10;i++)
{
if(tickets > 0)
System.out.println(Thread.currentThread().getName() + "卖掉了" + (tickets--) + "号票");
}
}
}
public class TestShared {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//1 线程对象
Thread thread1 = new MyThread(10);
//2 线程开启
thread1.start();//run()
//1 线程对象
Thread thread2 = new MyThread(10);
//2 线程开启
thread2.start();
}
}
class MyThread extends Thread
{
private static int tickets = 10;
public MyThread(int tickets)
{
//this.tickets = tickets;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<10;i++)
{
if(tickets > 0)
System.out.println(Thread.currentThread().getName() + "卖掉了" + (tickets--) + "号票");
}
}
}
public class TestSync {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Account account = new Account();
Thread thread1 = new Thread(new Withdraw(account), "卡");
Thread thread2 = new Thread(new Withdraw(account), "存折");
thread1.start();
thread2.start();
}
}
//账户
class Account
{
private int balance = 10000;//余额
//取款
public synchronized void withdraw(int count)
{
//同步代码块
//synchronized (this)
//{
if(balance >= count)
{
System.out.println(Thread.currentThread().getName() + "成功取款:" + count);
balance -= count;
System.out.println("余额:" + balance);
}
else
{
System.out.println("余额不足");
}
//}
}
}
class Withdraw implements Runnable
{
private Account acount;
public Withdraw(Account account) {
// TODO Auto-generated constructor stub
this.acount = account;
}
@Override
public void run() {
// TODO Auto-generated method stub
acount.withdraw(8000);
}
}
import java.util.LinkedList;
public class TestProducerConsumer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Warehouse warehouse = new Warehouse(10);//仓库
Thread thread1 = new Thread(new Producer(warehouse));//生产者线程
Thread thread2 = new Thread(new Consumer(warehouse));//消费者线程
thread1.start();
thread2.start();
}
}
//仓库
class Warehouse
{
private LinkedList<String> linkedList = new LinkedList<String>();//存放产品
private final int MAX;//仓库最大容量
private int id = 0;
public Warehouse(int max) {
// TODO Auto-generated constructor stub
MAX = max;
}
//添加一个产品
public synchronized void add()
{
if(linkedList.size() == MAX)
{
try {
System.out.println("满了,等待消费者唤醒");
this.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
String str = "产品" + id++;
linkedList.add(str);
System.out.println("生产了:" + str);
notify();
}
//取出一个产品
public synchronized void sub()
{
if(linkedList.size() == 0)
{
try {
System.out.println("空了,等待生产者唤醒");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("消费了:" + linkedList.getFirst());
linkedList.remove();
this.notify();//只会把在this上等待的线程唤醒一个
//this.notifyAll();//只会把在this上等待的线程全部唤醒
}
}
//生产者
class Producer implements Runnable
{
private Warehouse warehouse;//仓库
public Producer(Warehouse warehouse) {
// TODO Auto-generated constructor stub
this.warehouse = warehouse;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
warehouse.add();
}
}
}
//生产者
class Consumer implements Runnable
{
private Warehouse warehouse;//仓库
public Consumer(Warehouse warehouse) {
// TODO Auto-generated constructor stub
this.warehouse = warehouse;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
warehouse.sub();
}
}
}
public class TestInterupt {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread thread = new NewMyThread();
thread.start();
thread.interrupt();
}
}
class NewMyThread extends Thread
{
@Override
public void run() {
// TODO Auto-generated method stub
//System.out.println("线程要睡眠10秒");
synchronized (this)
{
System.out.println("线程要wait");
try {
wait(3000);
System.out.println("超时");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("被打断了");
}
}
}
}
public class TestJoin {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread thread = new NMThread(Thread.currentThread());
thread.start();
//thread.interrupt();
//主线程要等待子线程的结束
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("主线程的等待被打断");
}
System.out.println("主线程结束");
}
}
class NMThread extends Thread
{
private Thread mainThread;
public NMThread(Thread mainThread) {
// TODO Auto-generated constructor stub
this.mainThread = mainThread;
}
@Override
public void run() {
// TODO Auto-generated method stub
//System.out.println("线程要睡眠10秒");
for(int i=0;i<100;i++)
{
if(i==50)
mainThread.interrupt();
System.out.println(i);
}
System.out.println("子线程结束");
}
}
public class TestDeadlock {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Ch cha = new Ch("A");
Ch chb = new Ch("B");
Thread thread1 = new Thread(new Eat1(cha,chb));
Thread thread2 = new Thread(new Eat2(cha,chb));
thread1.start();
thread2.start();
}
}
//筷子
class Ch
{
private String name;
public Ch(String name) {
// TODO Auto-generated constructor stub
this.name = name;
}
}
class Eat1 implements Runnable
{
private Ch a;
private Ch b;
public Eat1(Ch a,Ch b) {
// TODO Auto-generated constructor stub
this.a = a;
this.b = b;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
synchronized (a) {
System.out.println("哲学家1获得A筷子");
synchronized (b) {
System.out.println("哲学家1获得B筷子");
System.out.println("哲学家1吃一口");
}
}
}
}
class Eat2 implements Runnable
{
private Ch a;
private Ch b;
public Eat2(Ch a,Ch b) {
// TODO Auto-generated constructor stub
this.a = a;
this.b = b;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
synchronized (a) {
System.out.println("哲学家2获得A筷子");
synchronized (b) {
System.out.println("哲学家2获得B筷子");
System.out.println("哲学家2吃一口");
}
}
}
}