线程实现方式:
1.继承java.lang.Thread,并重写它的run()方法,将线程的执行主体放入其中。
2.实现java.lang.Runnable接口,实现它的run()方法,并将线程的执行主体放入其中。
实现
java.lang.Runnable
接口,实现它的
run()
方法,并将线程的执行主体放入其中。
实现
java.lang.Runnable
接口,实现它的
run()
方法,并将线程的执行主体放入其中。
实现接口好处:避免了单继承的局限性 ,定义线程时建议使用实现方式区别:
thread代码存放在thread的子类run方法中
runnable代码存放在接口子类的run方法中
第一种方式
继承thread类
步骤:
1.定义类继承thread
2.复写thread类中的run方法
3.调用线程的start方法,此方法作用:启动线程和调用run
发现运行结果每次都不一样
因为多个线程都在获取cpu执行权。某一时刻只能有一个程序运行
cpu在快速切换已达到看上去同时运行效果
static thread currentthread();获取当前对象
getname()获取名字
*/
class demo extends Thread
{
//private String name;
demo(String name)
{
super(name);
//this.name = name;
}
public void run()//里面写运行代码用于start调用
{
for(int x=1; x<100; x++)
System.out.println((Thread.currentThread()==this)+"++"+this.getName()+"run--"+x);
}
}
class threaddemo1
{
public static void main(String[] args)
{
demo d1 = new demo("one--");//创建好一个线程.
demo d2 = new demo("two++");
d1.start();//开启线程并调用run方法
d2.start();
//d,run();仅仅是对象调用方法
for(int x=1; x<100; x++)
System.out.println("main--"+x);
}
}
创第二种方式:
实现runnable接口
步骤:
1.定义实现runnable接口
2.覆盖接口中run方法
3.通过thread类建立线程对象
4.将runnable接口中的子类对象作为实际参数传给thread的构造函数
5.调用thread类的start方法开启线程并调用runnable接口子类的run方法
通过分析可能出现0 -1 -2等错票
多线程运行出现安全问题
原因
当多条语句在操作同一个献策好难过共享数据时,一个线程对多条语句只执行一部分还没有执行完
当一个线程参与进来执行导致共享数据错误
解决办法
对多条操作共享的数据语句,智能让一个线程执行完,在执行过程中其他线程不参与执行
就是同步代码块
synchronized(对象)
{需要被同步的代码}保证只有一个线程在运行
好处:安全 坏处:每次判断,消耗资源
同步前提必需多个线程,线程必须使用同一个锁,而这个锁就是this
被静态修饰的锁不是this,因为静态方法中也不可以定义this,而是类名.class
*/
class ticket implements Runnable//extend Thread 定义实现runnable接口
{
private /*static*/int tick = 100;//总共一百张票
Object obj = new Object();
boolean flag = true;
public void run()//覆盖接口中run方法,把要运行的代码放在run方法中
{
if(flag)
{
while(true)
{
synchronized(this)//静态的锁ticket.class
{
if(tick>0)
{
try{Thread.sleep(1);}catch (Exception e){}
System.out.println(Thread.currentThread().getName()+"....sale++:"+tick--);
}
}
}//static thread currentthread();获取当前对象 getname()获取名字
}
else
while(true)
show();
}
public /*static*/ synchronized void show()//锁是this
{
if(tick>0)
{
try{Thread.sleep(2);}catch (Exception e){}
System.out.println(Thread.currentThread().getName()+"....sale--:"+tick--);
}
}
}
class threaddemo2
{
public static void main(String[] args)
{
ticket t = new ticket();
Thread t1 = new Thread(t);//将runnable接口中的子类对象作为实际参数传给thread的构造函数
Thread t2 = new Thread(t);//因为自定义run所属对象是runnable接口的子类对象
//Thread t3 = new Thread(t);//所以要让线程指定对象的run方法必须明确该run方法所属对象
//Thread t4 = new Thread(t);//如果不传没调用
t1.start();//调用thread类的start方法开启线程并调用runnable接口子类的run方法
try{Thread.sleep(1);}catch (Exception e){}
t.flag = false;
t2.start();
//t3.start();
//t4.start();
}
}