1.进程和线程
2.继承Thread类的方式实现多线程
3.设置和获取线程名称
4.线程优先级(线程调度)
public class MyThread extends Thread {
public MyThread(){
}
MyThread(String name){
super(name);
}
@Override
public void run() {
for (int i = 0;i<100;i++){
System.out.println(getName()+":"+i);
}
}
}
public class MyThreadDemo {
public static void main(String[] args){
MyThread thread = new MyThread();
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread.setName("高铁");
thread1.setName("飞机");
thread2.setName("汽车");
thread.setPriority(5);
thread1.setPriority(10);
thread2.setPriority(1);
thread.start();
thread1.start();
thread2.start();
}
}
5.线程控制
public class MyThread extends Thread {
public MyThread(){
}
MyThread(String name){
super(name);
}
@Override
public void run() {
for (int i = 0;i<100;i++){
System.out.println(getName()+":"+i);
//static void sleep(long millis)方法
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}
public class MyThreadDemo {
public static void main(String[] args){
MyThread thread = new MyThread();
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setName("关羽");
thread2.setName("张飞");
Thread.currentThread().setName("刘备");
thread1.setDaemon(true); //当主线程结束后,守护进程也thread1结束
thread2.setDaemon(true); //当主线程结束后,守护进程也thread2结束
// try {
// thread.join(); //thread执行结束后,其他线程才会执行
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
thread1.start();
thread2.start();
for (int i = 0;i<10;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
6.线程的生命周期
7.实现Runnable接口的方式实现多线程
8.线程同步
案例:卖票
卖票案例的思考:
代码如下:
public class SellTicket implements Runnable {
private int ticket=100;
@Override
public void run() {
//相同的票出现了多次
// while (true){
// if (ticket>0){
// try {
// Thread.sleep(500);
// //t1休息100毫秒
// //t2抢到执行权,t2开始执行,执行到这里休息100毫秒
// //t3抢到执行权,t3开始执行,执行到这里休息100毫秒
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// //假设线程按顺序醒过来
// //t1抢到执行权,正在输出窗口1售出第100张票
// System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
// //在t1线程的ticket--之前,t2醒过来,抢到执行全输出窗口2售出第100张票
// //在t1和t2线程的ticket--之前,t3醒过来,抢到执行全输出窗口3售出第100张票
// ticket--;
// //如果按顺序来,则ticket-3.变为97
// }
// }
//出现了负数的票
while (true){
//此时ticket=1
if (ticket>0){
try {
Thread.sleep(1);
//t1休息100毫秒
//t2抢到执行权,t2开始执行,执行到这里休息100毫秒
//t3抢到执行权,t3开始执行,执行到这里休息100毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//假设线程按顺序醒过来
//t1抢到执行权,正在输出窗口1售出第1张票
//假设t1继续拥有执行权,执行ticket--,则ticket=0
//t2抢到执行权,正在输出窗口1售出第0张票
//假设t2继续拥有执行权,执行ticket--,则ticket=-1
//t3抢到执行权,正在输出窗口1售出第-1张票
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
ticket--;
}
}
}
}
public class SellTicketDemo {
public static void main(String[] args) {
SellTicket st = new SellTicket();
//创建三个Thread对象
Thread td1 = new Thread(st,"窗口1");
Thread td2 = new Thread(st,"窗口2");
Thread td3 = new Thread(st,"窗口3");
//启动线程
td1.start();
td2.start();
td3.start();
}
}
买票案例数据安全的解决:
同步代码块:
public class SellTicket implements Runnable {
private int ticket=100;
private Object obj = new Object();
@Override
public void run() {
while (true){
synchronized (obj){
//ti进来后,就会吧这段代码锁起来,t2抢到执行权后因为这段代码被锁住了进不来
if (ticket>0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
ticket--;
}
}
//t1出来,锁解开,t2才可以进入
}
}
}
9.同步方法
public class SellTicket implements Runnable {
// private int ticket=100;
private static int ticket=100;
private Object obj = new Object(); //用同一把锁
int x=0;
@Override
public void run() {
while (true){
if (x%2==0){
//synchronized (this){ //同步方法:锁为this
synchronized (SellTicket.class){ //同步静态方法:锁为SellTicket.class
if (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
ticket--;
}
}
}else {
sellTicket();
}
x++;
}
}
//同步方法 :锁为this,和obj不是同一把锁
// private synchronized void sellTicket() {
// if (ticket>0){
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
// ticket--;
// }
// }
//同步静态方法 : 锁为SellTicket.class
private static synchronized void sellTicket() {
if (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
ticket--;
}
}
}
10.线程安全的类
public class ThreadDemo {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer(); //安全
StringBuilder sb2 = new StringBuilder(); //不安全
Vector<String> v =new Vector<>(); //安全
ArrayList<String> array = new ArrayList<>(); //不安全
Hashtable<String,String> st = new Hashtable<>(); //安全
HashMap<String,String> sm = new HashMap<>(); //不安全
//static <T> List<T> synchronizedList(List<T> list) 返回由指定列表支持的同步(线程安全)列表。
List<String> list = Collections.synchronizedList(new ArrayList<String>()); //把ArrayList包装成线程安全的集合类
}
}
11.Lock锁
public class SellTicket implements Runnable {
private static int ticket=100;
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
lock.lock(); //枷锁
if (ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第" + ticket + "张票");
ticket--;
}
}finally {
lock.unlock();//回放所
}
}
}
}
12.生产者和消费者
案例:
public class Box {
private int milk;
private boolean state = false;//表示奶箱状态
//存牛奶
public synchronized void put(int milk){
if (state){
try {
wait(); //等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有牛奶,就生产牛奶
this.milk=milk;
System.out.println("送奶工将第 "+this.milk+"送入奶箱");
//生产完后修改状态
state=true;
//唤醒其他线程
notify();
}
public synchronized void get(){
//如果没有牛奶 等待生产
if (!state){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有牛奶,就消费牛奶
System.out.println("用户拿到第 "+this.milk+"瓶奶");
//消费完毕
state = false;
//唤醒其他线程
notify();
}
}
public class Producer implements Runnable {
private Box b;
public Producer(Box b){
this.b = b;
}
@Override
public void run() {
for (int i = 1 ;i <= 5 ;i++){
b.put(i);
}
}
}
public class Customer implements Runnable {
private Box b;
public Customer(Box b) {
this.b = b;
}
@Override
public void run() {
while (true){
b.get();
}
}
}
public class BoxDemo {
public static void main(String[] args) {
Box b = new Box();
Producer p = new Producer(b);
Customer c = new Customer(b);
Thread t1 = new Thread(p); //生产者线程
Thread t2 = new Thread(c); //消费者线程
t1.start();
t2.start();
}
}