匿名内部类方式实现线程的创建
匿名:就是没有名字
内部类 : 写在其它类内部的类
匿名内部类的作用 : 简化代码
把子类继承父类,重写父类的方法,创建子类对象合成一步完成
把实现类实现类接口,重写接口中的方法,创建实现类对象合成一步完成
匿名内部类的最终产物 :
子类/实现类对象(这个类没有名字)
格式
new 父类/接口(){
重复父类/接口中的方法
};
实现
1.线程的父类是Thread
public class neibu {
public static void main(String[] args) {
new Thread() {
//重写run方法,设置线程任务
public void run() {
for(int i=0;i<3;i++)
System.out.println(Thread.currentThread().getName()+"zqc");
}
}.start();
}
}
2.线程的接口Runnable
public class neibu {
public static void main(String[] args) {
//线程的父类是Thread
new Thread() {
//重写run方法,设置线程任务
public void run() {
for(int i=0;i<3;i++)
System.out.println(Thread.currentThread().getName()+"zqc");
}
}.start();
Runnable r = new Runnable() {
public void run() {
for(int i=0;i<3;i++) {
System.out.println(Thread.currentThread().getName()+"handsome");
}
}
};
new Thread(r).start();
}
}
还可以简化一下接口,直接写在Thread()里面
线程安全问题
当使用多线程访问同一个资源的时候,且多个线程中对资源又写的操作,就容易出现线程安全问题。
比如一下代码三线程模拟售票系统
public class Thtext implements Runnable{
int tic =10;
public void run() {
while(true) {
if(tic>0)
{
try
{
Thread.sleep(100);
}
catch(Exception e) {
e.printStackTrace();
}
System.out.println("ticket"+tic--);
}
}
}
public static void main(String[] args) {
Thtext temp = new Thtext();
Thread t1=new Thread(temp);
Thread t2=new Thread(temp);
Thread t3=new Thread(temp);
t1.start();
t2.start();
t3.start();
}
}
运行之后发现
ticket10被重复售卖了三次,这就出现了线程安全问题(一张票怎么可以被卖三次呢)!!
线程同步机制
同步块
使用synchronized关键词。把对tic操作的代码设置在同步块中。代码如下
public class Thtext implements Runnable{
int tic =10;
public void run() {
while(true) {
synchronized("") {
if(tic>0)
{
try
{
Thread.sleep(100);
}
catch(Exception e) {
e.printStackTrace();
}
System.out.println("ticket"+tic--);
}
}
}
}
public static void main(String[] args) {
Thtext temp = new Thtext();
Thread t1=new Thread(temp);
Thread t2=new Thread(temp);
Thread t3=new Thread(temp);
t1.start();
t2.start();
t3.start();
}
}
把整个if语句,也是就操作了tic的语句都放在同步块中,这样就解决了线程安全问题。大致上的原理就是 一个线程1在执行的时候另外一个线程如果也想要执行这个,必须等,等到线程1执行完了之后在执行,这样tic每次–操作,如果同时执行就出错了。运行结果如下
同步方法
同步方法就是在方法面前加上一个synchronized关键词,然后再run方法中调用同步方法,就也解决了线程安全问题。
代码如下
public synchronized void doit() {
if(tic>0)
{
try
{
Thread.sleep(100);
}
catch(Exception e) {
e.printStackTrace();
}
System.out.println("ticket"+tic--);
}