进程:是一个正在执行中的程序。
每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。也就是说Thread类中的run方法,用于存储线程要运行的代码。
创建线程方法一:
class Demo extends Thread { public void run() { for(int x=0; x<60; x++) System.out.println("demo run----"+x); } } class ThreadDemo { public static void main(String[] args) { Demo d = new Demo();//创建好一个线程。 //d.start();//开启线程并执行该线程的run方法。 d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。 for(int x=0; x<60; x++) System.out.println("Hello World!--"+x); } }
步骤:
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法。
将线程要运行的代码存放在该run方法中。
3,通过Thread类建立线程对象。
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
为什么要将Runnable接口的子类对象传递给Thread的构造函数?
因为,自定义的run方法所属的对象是Runnable接口的子类对象。
所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。
5,调用Thread类的start()方法开启线程并调用Runnable接口子类的run方法。
【实现方法的好处】
1)避免了单继承的局限性
2)多个线程可以共享同一个接口子类的对象,非常适合多个相同线程来处理同一份资源。
class Ticket implements Runnable//extends Thread { private int tick = 100; public void run() { while(true) { if(tick>0) { System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--); } } } } class TicketDemo { public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t);//创建了一个线程; Thread t2 = new Thread(t);//创建了一个线程; Thread t3 = new Thread(t);//创建了一个线程; Thread t4 = new Thread(t);//创建了一个线程; t1.start(); t2.start(); t3.start(); t4.start(); } }
需求:
银行有一个金库。
有两个储户分别存300元,每次存100,存3次。
目的:该程序是否有安全问题,如果有,如何解决?
如何找问题?
1,明确哪些代码是多线程运行代码。
2,明确共享数据。
3,明确多线程运行代码中哪些语句是操作共享数据的。
package com.tan; class Bank{ private int sum; //让函数具备同步性- //同步有两种表现形式:1、同步代码块 2、同步函数 public synchronized void add(int n){ sum=sum+n; try { Thread.sleep(10); } catch (Exception e) { e.toString(); } System.out.println("sum="+sum); } } class Cus implements Runnable{ Bank bank =new Bank(); @Override public void run() { for(int i=0;i<3;i++){ bank.add(100); } } } public class BankDemo{ public static void main(String[] args) { Cus cus=new Cus(); Thread t1=new Thread(cus); Thread t2=new Thread(cus); t1.start(); t2.start(); } }