获取当前线程的名称有以下方法:
Thread.currentThread().getName();
可以通过setName()对线程进行定义名称,通过getName()来获取名称;或者可以通过再构造函数中调用super(name)来获取定义好的线程名称;
线程都有自己的默认名称,一般是Thread 加编号,编号一般从0开始;
二: 售票程序例子,多个窗口买票
class Tiket extends Thread
{
private static int tiketCount = 100;
//1:如果就是int,那么有多少线程去卖,就会卖多少线程数乘以100数;
//2:如果是static ,能控制统一卖100张,但是static的周期太长,性能不好; private static int tiketCount=100;
//这种方式创建线程不靠谱,解决方法,采用第2中方式来解决,就是implements Runnable接口来实现;
public void run(){
while(true){
if(tiketCount>0){
System.out.println(currentThread().getName+"tiket"+tiketCount-- );
}
}
}
}public class TiketMain{
public static void main(String args[]){
Tiket tiket1 =new Tiket();
Tiket tiket2 =new Tiket();
Tiket tiket3 =new Tiket();
Tiket tiket4 =new Tiket();
tiket1.start();
tiket2.start();
tiket3.start();
tiket4.start();
}
}
2:实现方式二步骤
a:编写实现Runnable接口类;
b:重写Runnable接口的run方法;
c:通过Thread类建立线程对象;
d:将Runnable子类的实例对象作为Thread构造函数的参数,建立与Thread和Runnable子类的联系;
e:调用start方法启动线程,并调用Runnable接口的run方法,那么前面那个票数就不需要定义为static,多少个Thread对象类就会分配这个票数;
class Titket impements Runnable{
void run{}
}public class TitketMain {
public static void main(String args[]){
Titket titket = new Titket();
Thread thread1= new Thread(titket);
Thread thread2 = new Thread(titket);
......
thread1.start();
thread2.start();
}
}
接口方法不能用throws抛出异常,如果抛出异常,程序就会runtime,终止运行,只能通过try、catch方式来捕获异常;
多线程程序中最重要的问题是,多个线程同时共享一个资源的时候,会出现线程安全问题,通过使用同步代码块来进行处理:
class titket implements Runnable{
private int titketCount= 100;
Object obj =new Object();
public void run(){
while(true){
Synchronized(obj){
if(titketCount>0){
try{Thread.sleep(10);}catch(Exception ex){}
System.out.println(currentThread.getName+"titket run"+titketCount --);
}
}
}
}
同步的经典例子----火车车厢中的WC;
同步的条件:
1:必须具备两个或两个以上的线程存在;
2:两个以上的线程同时共享一个资源,使用同一个锁;
三:多线程的线程安全
1:如何找出问题;
a:明确哪些代码是多线程运行代码;
b:明确共享数据;
c:明确多线程运行代码中那些是操作共享数据的;
class Bank
{
private int sum;
Object obj = new Object();
public void add(int n)throws Exception{
Synchronized(obj){
sum = sum+n;
Thread.sleep(10);
System.out.println("sum="+sum);
}
}
}class Cus implements Runnable{
Bank bank = new Bank();
public void run(){
for(int x=0;x<3;x++){
try{
bank.add(100);
}catch(Exception ex){
}
}
}
}public class CusMain{
public static void main(String args[]){
Cus cus = new Cus();
Thread thread1 = new Thread(cus);
Thread thread2 = new Thread(cus);
....
}
}
同步有两种表现方式:同步代码块和同步函数
以上代码如果需要更改成同步函数来完成,代码如下:
class Bank
{
private int sum;
//Object obj = new Object();
public Synchronized void add(int n)throws Exception{
//Synchronized(obj){
sum = sum+n;
Thread.sleep(10);
System.out.println("sum="+sum);
// }
}
}
在程序运行中,如果需要暂停下main方法中的主线程,可以通过Thread.sleep(10);来实现;同步函数锁的对象是this,当前对象,如果使用同步代码块和同步函数同时使用,但是锁的对象不是同一个对象,那么肯定会存在问题。
四:多线程-静态同步函数的
如果同步函数被static修饰后,使用的锁是什么呢?
通过发现,对象不再是this,因为静态方法中也不可以定义this;
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,类名.class,该对象的类型为class;
静态同步函数锁也是字节码文件对象,类名.class,该对象的类型也是为class。
通过同步代码更改为如下:
class Bank
{
private int sum;
//Object obj = new Object();
public void add(int n)throws Exception{
Synchronized(Bank.class){ //匹配下面static 同步函数
sum = sum+n;
Thread.sleep(10);
System.out.println("sum="+sum);
}
}public static Synchronized show(){ //也是对应于Bank.class
..........................
}
}
五:day11-14-多线程 多线程-单例设计模式-懒汉式
1:饿汉式
class Single{
private static final Single s = new Single();
public Single(){}
public static Single getInstance(){
return s;
}
2:懒汉式
class Single{
private static Single s = null;
public Single(){}
public static Single getInstance(){
if(null == s){
s = new Single();
return s;
}
}
懒汉式也叫延迟加载,例如if(null == s){ s = new Single();
如果是多线程同时共享懒汉式,就会执行 new Single()对象很多次,解决办法如下:
public static Synchronized Single getInstance(),不过没个线程进来都需要判断下,懒汉式同步性能是最低效的,不建议使用;
不过用双重否判断可以解决,一般都采用饿汉式单例模式,修改语句如下:
class Single{
private static Single s = null;
public Single(){}
public static Single getInstance(){
if(null == s){
Synchronized(Single.class){
if(null == s){
s= new Single();
}
}
}
}
}
六:day11-15-多线程(多线程-死锁)
死锁:同步中嵌套同步,但是锁却不同;机器不同,有可能这台机出现死锁,其它机不重现死锁情况,可以通过whrte(true)来发现排除。有可能出现和谐状态,就不会发现死锁情况。
Class Cou{
Object a = new Object();
Object b = new Object();
}class ThreadTest implements Runnable{
Cou cou = new Cou();
private boolean flag;
public void run(){
if(flag){
Synchronized(cou.a){
Synchronized(cou.b){
}
}
}else{
Synchronized(cou.b){
Synchronized(cou.a){
}
}
}
}
}