传智播客——毕向东25--第11天总结-10
来源:互联网 发布:四层别墅网络覆盖方案 编辑:程序博客网 时间:2024/05/01 09:00
多线程
进程:是一个正在执行的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径或者叫一个控制单元。
线程:是进程中的一个独立的控制单元。线程在控制着进程的执行
一个进程中至少有一个线程
创建线程
方式一:继承Thread类,并重写run方法
a.定义类并继承Thread类;
b.重写Thread类中的run方法;
c.调用线程的satrt方法;
class Demo extends Thread
{
public void run()
{
for(int x=0;x<60;x++)
System.out.println("demo run......");
}
}
class ThreadDemo
{
public static void main(String[]args)
{
Demo d=new Demo();
d.start();
for(int x=0;x<60;x++)
System.out.println("Hello Word!");
}
}
JVM在启动的时候会有一个进程java.exe,该进程中至少一个线程负责java程序的执行,而且这个线程运行的代码存在于main方法中,该线程称为主线程。
run和start的特点:
run()方法:仅是对象调用的方法;
start()方法:开启线程并执行该线程run方法
例:创建两个线程和主线程交替运行:
class Test extends Thread
{
private String name;
Test(String name)
{
this.name=name;
}
public void run()
{
for(int x=0;x<60;x++)
System.out.println(name+"run......"+x);
}
}
class ThreadTest
{
public static void main(String[] args)
{
Test t1=new Test("one");
Test t2=new Test("two");
t1.start();
t2.start();
for(int x=0;x<60;x++)
System.out.println("main......"+x);
}
}
获取线程对象以及名称:
getName():获取线程名称
线程有自己默认的名称:Thread-编号(编号从0开始)
static Thread currentThread():获取当前线程对象
例:Thread.currentThread().getName():返回当前对象
售票的例子:继承Thread的方式:
class Ticket extends Thread
{
private static int tick=100;
public void run()
{
while(true)
{
if(tikc>0)
System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
}
}
}
class TicketDemo
{
public static void main()
{
Ticket t1=new Ticket();
Ticket t2=new Ticket();
Ticket t3=new Ticket();
Ticket t4=new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
方式二:实现Runable接口:
步骤:1.定义类实现Runnable接口;
2.覆盖Runnable接口中的run方法
3.通过Thread类建立线程对象
4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法;
售票的例子:实现Runnable的方式:
class Ticket implements Runnable
{
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();
}
}
继承Thread和实现Runnable两种方式的区别:
继承Thread:线程代码存放Thread子类run()方法中
实现Runnable:线程代码在接口的子类run()方法中
多线程的安全问题:
CPU在进行切换执行时,会使线程停留在一个错误的位置,售票系统会产生票数为负的情况;
解决方法:同步代码块
语法:synchronized(对象)
{
需要同步的代码;
}
同步代码块示例:
:
:
:
while(true)
{
synchronized(obj); //Object obj=new Object();
{
if(tick>0)
{
try{Thread.sleep(10);}
catch (Exception e){}
System.out.println(Thread.currentThread().getName()+"...sale:"+tick--);
}
}
}
对象如同锁,持有锁的线程可以再同步中执行;
线程同步的前提:
1.必须要有两个或两个以上的线程
2.必须是多个线程使用同一个锁
同步函数:
同步函数:在函数上加入synchronized关键字
例:public synchronized void add()
{......}
示例:有两个储户分别存300元,每次存100,存了3次
class Bank
{
private int sum;
public synchronized void add(int n)
{
sum=sum+n;
try{Thread.sleep(10);}
catch(Exception 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);
}
}
}
class BankDemo
{
public static void main(String[] args)
{
Cus c=new Cus();
Thread t1=new Thread(c);
Thread t2=new Thread(c);
t1.start();
t2.start();
}
}
同步函数默认的锁是this:
.....
public void run()
{
while(true)
{
synchronized(this) //this当前同步函数对象
{... ...}
}
}
public synchronized void show() //同步函数
{
... ...
}
静态同步函数的锁是class对象:
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象:类名.class 该对象类型是class;
静态的同步方法,使用的锁是该方法所在类的字节码文件对象 类名.class;
private static int tick=100;
......
synchronized(Ticket.class) //字节码文件对象
......
class Ticket
{
......
public static synchronized void show()
......
}
单例设计模式:
//饿汉式:
class Single
{
private static final Single s=new Single();
private Single(){}
public static Single getInstance()
{return s;}
}
//懒汉式:线程同步
class Single
{
private static Single s=null;
private Single(){}
public static Single getInstance()
{
if(s==null) //判断1
{
synchronized(single.class) //字节码文件对象
{
if(s==null) //判断2 双重判断解决低效问题
//-->A
//-->B
s=new Single();
}
}
return s;
}
}
多线程-死锁:
......
puclic void run
{
if(flag)
{
synchronized(MyLock.locka) //有a锁要b锁
{
System.out.println("if locka");
synchronized(MyLock.lockb)
{
System.out.println("if lockb");
}
}
}
else
{
synchronized(MyLock.lockb) //有b锁要a锁
{
System.out.println("else lockb");
synchronized(MyLock.locka)
{
System.out.println("else locka");
}
}
}
}
class MyLock
{
static Object locka=new Object();
static Object lockb=new Object();
}
......
- 传智播客——毕向东25--第11天总结-10
- 传智播客——毕向东25--第10天总结-9
- 传智播客——毕向东25--第4天总结-3
- 传智播客——毕向东25--第5天总结-4
- 传智播客——毕向东25--第6天总结-5
- 传智播客——毕向东25--第7天总结-6
- 传智播客——毕向东25--第8天总结-7
- 传智播客——毕向东25--第9天总结-8
- 毕向东异常总结
- I010-黑马程序员_毕向东_Java基础视频教程第01天-10-注释
- 毕向东java基础总结
- 毕向东Java知识总结
- Java基础入门(25天) 毕向东
- 毕向东25天学习目录
- 正则表达式——毕向东java
- Java毕向东01——笔记
- 黑马程序员 GUI开发总结 毕向东
- 4.毕向东_集合框架总结
- jsp和Servlet中文乱码汇总
- Python中inner function的binding处理
- wget linux
- iphone NSData
- Hibernate4实战 之 第二部分:Hibernate的基本配置
- 传智播客——毕向东25--第11天总结-10
- 马来西亚汽车巨擘Proton联手运营商Yes首推4G汽车
- vector小点
- 关于CAD中不显示黑体或是黑体字显示为问号的原因
- html li 背景色 大小
- 使用http连接到Analysis services
- 在IIS上部署基于django WEB框架的python网站应用
- 自省
- 分布式测试框架介绍