------- android培训、java培训、期待与您交流! ----------
1.什么是线程?
又称轻量级进程,是程序执行流的最小单元。
2.线程与进程的区别?
进程:是一个正在执行中的程序,每一个进程都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中一个独立的控制单元,线程在控制这进程的执行。简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
3.什么是多线程?
在单个程序中同时运行多个线程完成不同的工作称为多线程。
4.多线程有多少种创建方式,都是怎样的?
有两种。第一种是继承Thread类。步骤为:1.定义类继承Thread。 2.复写Thread类中的run方法。 3.调用线程的start方法,该方法有两个作用,开启线程和调用run方法。代码如下:package exercise;
public class Test1 {
public static voidmain(String[] args) {
xc x=new xc();//创建线程对象。
x.start();//开启线程和调用run方法。
}
}
class xc extends Thread//继承Thread类
{
public void run()
{
System.out.println("复写run方法");
}
}
第二种为实现Runnable接口。步骤为:1.定义类实现Runnable接口。 2.覆盖Runnable接口中的run方法。 3.通过Thread类建立线程对象。 4.将Runnable接口中的子类对象作为实际参数传递给Thread类的构造函数。5.调用Thread类的start方法开启线程并调用Runnable接口子类的ruan方法。代码如下:
package exercise;
public class Test2 {
public static voidmain(String[] args) {
xc2 x=new xc2();
Thread t=newThread(x);
t.start();
}
}
class xc2 implements Runnable
{
public void run()
{
System.out.println("覆盖Runnable接口中的run方法");
}
}
5.多线程的安全问题。
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来。导致共享数据的错误。例如,卖票问题中会出现卖出0或者-1张票。
6.解决多线程安全问题的两种方法,同步代码块和同步函数。
通过例子卖票问题来了解这两种方法
package exercise;
public class chapiao {
public static voidmain(String[] args) {
xc8 lx=new xc8();
xc8 lc=new xc8();
Thread aa=newThread(lx);
Thread ee=new Thread(lc);
aa.setName("1");
ee.setName("2");
aa.start();
ee.start();
}
}
class xc8 implements Runnable
{
public static int chepiao=100;
static String ff=new String("1");
public void run()
{
while (true)
{
synchronized(ff)
{
if(chepiao>0)
{
System.out.println("第"+Thread.currentThread().getName()+
"个火车站正在售第"+(101-chepiao)+"张车票");
--chepiao;
}
else
{
break;
}
}
}
}
}
这其中synchronized(ff)大括号中的代码就为需要同步的代码,形如synchronized(对象){需要被同步的代码},其中对象是任意的。对象也称为锁,持有锁的线程可以在同步中执行,没有锁的线程即使获得cpu的执行权,也进不去。
同步函数其实就是将synchronized放到函数的修饰中去,形如pubilc synchronizedvoid run(){},在这里整个函数里面的代码都被同步了,其中普通同步函数的锁为this,静态同步函数的锁为字节码文件对象,形如类名.class,该对象的类型是class。
7.多线程单例设计模式
代码如下
package exercise;
class single {
private static single s=null;
private single(){}
public static single getInstance()
{
if(s==null)
{
synchronized(single.class)
{
if(s==null)
{
s=new single();
}
}
}
returns;
}
}
public class tblhs
{
public static voidmain(String[] args) {
System.out.println("单例设计模式");
}
}
这里的懒汉式单例设计模式结合多线程的面试题常为,饿汉式和懒汉式的区别?懒汉式可以延迟加载。延迟加载有没有问题?有,如果多线程方位时会出现安全问题。解决方法为同步方法,同步代码块和同步函数都可以,并用双重判断提高效率。
8.死锁:当同步中嵌套同步容易死锁。
9.多线程间的通讯。
例程:input->资源->output,就像挖煤一样,一个线程负责送煤,一个线程负责出煤,也就是一进一出。总而言之:多线程在操作用一个资源,但执行的动作不一样。
10.等待唤醒机制
解决多线程通讯的安全问题,可以实现一进一出的稳定模式,而不会出现两进一出或者一进两出的模式。例子如下:
package exercise;
class Res
{
private String name;
private String sex;
private boolean flag=false;
public synchronized void set(String name,Stringsex)
{
if(flag)
try
{
this.wait();
}
catch(Exception e)
{}
this.name=name;
this.sex=sex;
flag=true;
this.notify();
}
public synchronized void out()
{
if(!flag)
try
{
this.wait();
}
catch(Exception e)
{}
System.out.println(name+"..."+sex);
flag=false;
this.notify();
}
}
class Input implements Runnable
{
private Res r;
Input(Res r)
{
this.r=r;
}
@Override
public void run()
{
// TODO Auto-generated method stub
int x=0;
while(true)
{
if(x==0)
{
r.set("mike","man");
}
else
{
r.set("小丽","女");
}
x=(x+1)%2;
}
}
}
class Output implements Runnable
{
private Res r;
Output(Res r)
{
this.r=r;
}
@Override
public void run()
{
while(true)
{
r.out();
}
// TODO Auto-generated method stub
}
}
public class inputoutputtest
{
public static void main(String[] args)
{
Res r=new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}
}
11.多线程生产者消费者中JDK5.0的升级。形如
private lock lock=new Reentrantlock();
private Condition condition_pro=lock.newCondition();
private Condition condition_con=lock.newCondition();//不同的condition对象
lock.lock();
try
{
语句
}
finally
{
lock.unlock();//释放锁
}
这种升级方式由于可以创建不同的condition对象,所以可以让进的线程唤醒出的进程,不会由于多线程的随机性出现凌乱。
12.学习总结
本章主要的知识点是创建多线程,多线程的安全问题和多线程的通讯。这其中的安全问题和通讯中出现的凌乱现象都是因为cpu运行线程的随机性引发的,所以不能盲目使用多线程,当解决一个问题时能不使用尽量不去使用,其中不仅安全问题多多,运行效率也低。