import java.util.*;
public static void main(String[] args) {
/*
final可以修饰类,方法,变量。
final修饰的类不可以被继承。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量。只能被赋值一次。
内部类只能访问被final修饰的局部变量。
*/
/*抽象类和抽象方法
*/
/*
接口
*/
/*try catch
在try块,catch块,finally块和异常块外存在return语句的情况。finally中的return是会提前退出的,
finally中的代码在其他两块中中存在return是要运行的,只不过不会改变return中结果。
*/
/**
1. 线程定义的两种方法,
第一是继承Thread类并覆盖run方法,start()方法调用run()方法开启线程和任务。run()方法只是主函数中的一个普通方法不会开启多线程。由于java不支持多继承,当需要多线程的子类有父类时,可以通过接口的方式实现多继承。所以出现第二种方法。
第二是实现runable接口,并实现接口中的run方法,把线程任务封装在run方法中,通过Thread类创建线程对象。
2. 线程中的方法
调用当前线程:Thread.currentThread().getName();
start(),stop(),sleep(time),wait(),notify()
构造方法:Thread();Thread(Runnable r)通过Thread的这个构造方法传递定义好的Runnable子类接口实现第二种方法的多线程创建;
3.线程的状态
cpu的执行资格:可以被cpu的处理,在处理队列中排队
cpu的执行权:正在被cpu的处理
①被创建,
②运行:具备执行资格和执行权,
③冻结:释放执行权和执行资格,
④消亡:
⑤临时阻塞:具备执行资格还不具备执行权
4.线程中的问题
各线程之间互相不会干扰
class Thread
{
private Runnable r;
Thread()
{
}
Thread(Runnable r)
{
this.r = r;
}
public void run()
{
if(r!=null)
r.run();
}
public void start()
{
run();//如果实现子线程类调用的是子线程中实现的run方法,子线程中的run()覆盖了父类Thread中的方法。
}
}
//第一种创建多线程的方法
class SubThread extends Thread
{
public void run()
{
System.out.println("haha");
}
}
//第二种创建多线程的方法
//单独将任务封装起来,按照面向对象的思想将任务封装成对象,避免了java单继承的局限性
class ThreadImpl implements Runnable
{
public void run()
{
system.out.println("runnable run");
}
}
ThreadImpl i = new ThreadImpl();
Thread t = new Thread(i);
t.start();
5.//多线程卖票
public class Ticket extends Thread{
private int num = 100;
//private static int num = 100;//静态变量实现唯一
public void run(){
while(true){
if(num>0){
system.out.println(Thread.currentThread().getName()+"...."+num--);
}
}
}
}
class ticketDemo{
public static void main(String[] args){
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
//Ticket t2 = new Ticket();
//Ticket t3 = new Ticket();
//Ticket t4 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
//t1.start();t1.start();t1.start();t1.start();
}
}
//多线程卖票,实现Runnable接口实现
public class Ticket implements Runnable{
private int num = 100;
//private static int num = 100;//静态变量实现唯一
public void run(){
while(true){
if(num>0){
system.out.println(Thread.currentThread().getName()+"...."+num--);
}
}
}
}
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();
//t1.start();t1.start();t1.start();t1.start();
}
}
6.线程中的安全问题:
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
当编号num为1的线程切换为冻结状态,有执行资格但没有执行权的时候。下一个线程可以运行,当切换的线程切换过来后,会出现0号票的情况,线程安全出现问题。
原因:多个线程操作共享的数据;操作共享数据的线程代码有多条;
public void run(){
private int num = 100;
public void run(){
while(true){
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+num--);
}
}
}
}
线程安全问题的解决,线程代码块的同步(火车上的卫生间),由于同步外的线程都要判断同步锁,所以相应的降低了效率。
同步去前提:同步中必须有多个线程并使用同一个锁
public void run(){
private int num = 100;
object obj = new object();
public void run(){
while(true){
synchronize(obj)
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+num--);
}
}
}
}
}
7.//银行储户的例子
class Bank
{
private int sum;
private Object obj = new Object();
public void add(int num)
{
synchronized(obj)//同步代码块在调用的地方。
{
sum = sum + num;
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println("sum="+sum);
}
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0; x<3;x++)
{
b.add(100);
}
}
}
//银行储户的例子(同步关键字作为函数的修饰符)(同步代码块到同步函数的转换)
//同步函数使用的锁是this,所以在同步代码块和同步函数混合使用的时候在同步代码块加的锁为this。
//同步函数和同步代码块的区别
1,同步函数的锁是固定的this
2,同步代码块是任意的对象
3,同步代码块的使用较多。
//静态同步函数的锁
1,在同步代码块加锁的时候与同步函数的区别
synchronize(this)
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptException e){}
System.out.println(Thread.currenThread.getName()+num--);
}
}
2,在同步代码块加锁的时候与同步函数的区别
静态的同步函数使用的锁是 该函数所属字节码文件对象,
可以用getClass方法获取,也可以用当前类名.class表示
synchronize(this.getClass())//this是当前票对象
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptException e){}
System.out.println(Thread.currenThread.getName()+num--);
}
}
class Bank
{
private int sum;
private Object obj = new Object();
public synchronized void add(int num)//同步函数
{
// synchronized(obj)//同步代码块在调用的地方。
// {
sum = sum + num;
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println("sum="+sum);
// }
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0; x<3;x++)
{
b.add(100);
}
}
}
8.//多线程下的单例设计模式
//饿汉式的
class Single
{
private static final Single s = new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}
//懒汉式
calss Single
{
private static Single s = null;
private Single(){}
public static synchronized Single getInstance()
{
if(s==null){//解决效率问题
synchronized(Single.class){//此处不能用this.getClass()因为getclass方法是非静态的。
if(s==null)
s = new Single();
}
}
}
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("hello world!");
}
}
//枚举类来实现
public enum animalHelperSingleton{
INSTANCE;
private AnimalHelperSingleton(){}
public Animal[] buildAnimalList(){
final Animal[] animals = new Animal[10];
animals[0] =new SimpleAnimal(Animal.AnimalClass.MAMMAL, "DOG0", TRUE,COLOR.GRAY);
animals[0] =new SimpleAnimal(Animal.AnimalClass.MAMMAL, "DOG1", TRUE,COLOR.GRAY);
animals[0] =new SimpleAnimal(Animal.AnimalClass.MAMMAL, "DOG2", TRUE,COLOR.GRAY);
animals[0] =new SimpleAnimal(Animal.AnimalClass.MAMMAL, "DOG3", TRUE,COLOR.GRAY);
return animals;
}
}
9.死锁:代码块中的锁有同步函数的锁,同步函数的锁中有代码块的锁,两个线程每个拿到一半资源,互不相让。
死锁实例
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
while(true)
{
synchronized(MyLock.locka)
{
System.out.println(thread.current.getName()+"if locaka..");
synchronized(MyLock.lockb)
System.out.println(thread.current.getName()+"if locakb..");
}
}
}
else
{
while(true)
{
synchronized(MyLock.lockb)
{
System.out.prinln(thread.current.getName()+"else lockb...");
synchronized(MyLock.locka)
{
System.out.println(thread.current.getName()+"else locka...");
}
}
}
}
}
}
class MyLock
{
pbulic static final Object locka = new Object();
public static final Object lockb = new Object();
}
*/
/**
10.线程通信
多个线程在处理统一资源,但是任务不同
等待唤醒机制 ,wait(),notify(),notifyall()
//资源
class Resource
{
String name;
String sex;
boolean flag = false;
}
//输入
class Input implements Runnable
{
Resource r;
input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(r.flag)
r.wait();
if(x==0)
{
r.name="mike";
r.sex="nan";
}
else
{
r.name="丽丽";
r.sex="女女女女女";
}
r.flag = true;
r.notify();
}
x = (x+1)%2;
}
}
}
//输出
class Output implements runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!flag)
r.wait();
System.out.println(r.name+"..."+r.sex);
r.flag = false;
r.notify();
}
}
}
}
class RsourceDemo2
{
public static void main(String[] args)
{
//创建资源
Resource r = new Resource();
//创建任务
Input in = new Input(r);
Output out = new Output(r);
//定义线程
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
//开启线程
t1.start();
t2.start();
}
}
/*
11.等待唤醒机制,生产者消费者模式
class Resouce
{
private String name;
private int count=1;
private boolean flag = false;
public void set(String name)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者。。。。"+this.name);
flag = true;
notify();
}
public void out()
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者。。。。。"+this.name);
flag = false;
notify();
}
}
class producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.out();
}
}
}
class consumer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
//创建资源
Resouce r = new Resource();
//创建任务
Producer pro = new Producer();
Consumer con = new Consumer();
//创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//开启线程
t1.start();
t2.start();
}
}
12.//多生产和多消费的问题
class Resouce
{
private String name;
private int count=1;
private boolean flag = false;
public void set(String name)
{
while(flag)//多次判断,让阻塞的线程继续判断标记,解决了线程获取执行权后是否要运行。
try{this.wait();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者。。。。"+this.name);
flag = true;
notifyAll();//唤醒所有,解决了死锁问题。
}
public void out()
{
while(flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者。。。。。"+this.name);
flag = false;
notifyAll();
}
}
class producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.out();
}
}
}
class consumer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
//创建资源
Resouce r = new Resource();
//创建任务
Producer pro = new Producer();
Consumer con = new Consumer();
//创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//开启线程
t1.start();
t2.start();
}
}
*/
//多生产和多消费的问题,由于为了防止多消费者和多生产者多线程中的死锁问题,
//在消费者和生产者完成相应操作后必须把线程池中阻塞的线程进行全部唤醒,这样会导致
//一个问题就是,每次唤醒的线程中会有本方的线程,虽然通过while判断进行再次wait阻塞并放入线程中
//但是这样会浪费系统的开销。所以必须实现在同一个锁中的多个任务多线程操作,这样就引出了同一个锁中的多个监视器的感念。
//由于生产者和消费者所处的监视器可以分开,所以在唤醒操作中,可以实现只唤醒对方的线程任务。
//这个实现方法通过java1.5中的新特性,LOCK接口实现 ,通过实例化lock接口的子类来定义多个监视器。
//condition接口:出现替代了object中的wait,notify notifyAll方法
// 将这些监视器方法单独进行封装,变成Condition监视器对象。
// 可以任意锁进行组合。
// await(); wait();
// signal(); notify();
// signalAll(); notifyAll();
/*
class Resouce
{
private String name;
private int count=1;
private boolean flag = false;
//创建一个锁对象
Lock lock = new();
//通过已有锁获取该锁上的两组监视器对象
Condition producer_con = lock.newcondition();
condition consumer_con = lock.newCondition();
public void set(String name)
{
while(flag)//多次判断,让阻塞的线程继续判断标记,解决了线程获取执行权后是否要运行。
try{producer_con.await();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者。。。。"+this.name);
flag = true;
consumer_con.singleAll();//唤醒所有,解决了死锁问题。
}
public void out()
{
while(flag)
try{consumer_con.await();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者。。。。。"+this.name);
flag = false;
consumer_con.singleAll();
}
}
class producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.out();
}
}
}
class consumer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
//创建资源
Resouce r = new Resource();
//创建任务
Producer pro = new Producer();
Consumer con = new Consumer();
//创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//开启线程
t1.start();
t2.start();
}
}
*/
}