您的位置:首页 > 编程语言 > Java开发

Java知识总结-多线程

2014-02-15 23:36 316 查看
说明:关于多线程,同步问题是我有待加强的知识点。

一、线程的创建。

创建线程可以通过两种方式:

方式一,自定义一个类,继承Thread类并重写run()方法。例:

//自定义类继承Thread类
class MyThread extends Thread{
//重写run()方法
public void run(){
System.out.println("重写run()方法");
}
}
public class Test {
public static void main(String[] args){
//创建Thread子类对象
MyThread mt=new MyThread();
//通过调用start()方法,开启新线程,同时执行run()方法
mt.start();
}
}

方式二,自定义一个类,实现Runnable接口。

//自定义类实现Runnable接口
class MyClass implements Runnable{
//重写run()方法
public void run(){
System.out.println("重写run()方法");
}
}
public class Test {
public static void main(String[] args){
//创建Runnable子类对象
MyClass mc=new MyClass();
//将对象作为参数传入Thread的构造函数,创建Thread类对象
Thread t=new Thread(mc);
//通过调用Thread类的start()方法,开启新线程,同时执行run()方法
t.start();
}
}
上面创建线程的两种方式里,方式二可以避免Java中单继承的问题,当一个类有父类时,可以通过实现Runnable接口来定义线程。

二,线程的操作

在Thread类中,有些常见的操作线程的方法。

------getName():返回该线程的名称,返回值类型:String。

//自定义类实现Runnable接口
class MyClass implements Runnable{
//重写run()方法
public void run(){
System.out.println("重写run()方法");
}
}
public class Test {
public static void main(String[] args){
//创建Runnable子类对象
MyClass mc=new MyClass();
//将对象作为参数传入Thread的构造函数,创建Thread类对象
Thread t=new Thread(mc);
//获取线程名称
System.out.println(t.getName());
}
}

运行结果:

Thread-0

这时返回的线程名称是系统默认的名称,也可以通过getName()方法自定义线程的名称。

------setName(String name):改变线程名称,使之与参数name相同。

//自定义类实现Runnable接口
class MyClass implements Runnable{
//重写run()方法
public void run(){
System.out.println("重写run()方法");
}
}
public class Test {
public static void main(String[] args){
//创建Runnable子类对象
MyClass mc=new MyClass();
//将对象作为参数传入Thread的构造函数,创建Thread类对象
Thread t=new Thread(mc);
//自定义线程名称
t.setName("自定义线程 Myclass");
//获取线程名称
System.out.println(t.getName());
}
}


运行结果:

自定义线程 Myclass

这时线程的名称就变为我们设置的名字。

------sleep(long millis):使正在执行的线程休眠(暂停执行),返回值类型:void;静态方法。

注,该方法已经声明异常,当我们在run()方法内调用sleep()时,需要对异常已经处理,因为Thread类中的run()方法并没有抛出异常,所以重写run()时也不可以抛出异常,只能对异常进行try{}catch{}处理。

class MyClass extends Thread{
public void run(){
for(int x=0;x<100;x++){
try {
//使线程休眠20毫秒
sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
}

-------wait():使当前线程等待。返回值类型:void;

注:如果当前线程被wait()方法操作导致等待时,该线程会自动放弃在CPU中的执行权和执行资格,系统CPU会随机执行其他具备执行资格的线程。

class MyClassA extends Thread{
public void run(){

for(int x=0;x<100;x++){

try {
if(x==10)
//使线程等待
wait();
} catch (InterruptedException e) {
//异常处理
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
}


------notify():唤醒与当前线程同步的线程中的单个等待线程;

------notifyAll():唤醒与当前线程同步的线程中的所有等待线程;

------interrupt():中断线程的休眠和等待状态,使线程继续运行。

------join():等待该调用线程执行完毕后,原线程继续执行。

------setDaemon():将该线程标记为守护线程,当主线程运行结束时,守护线程随之结束。

------setPriority(int newPriority):更改线程的优先级。

------yiekd(): 暂停当前线程,并执行其他线程。

三,同步

当多个线程共享同一资源时,

同步的前提:

1.必须要有两个或者两个以上的线程;

2.必须是多个线程使用同一个锁。

同步的作用:通过同步是多个线程只能有一个线程在运行,

好处:解决了多线程的安全问题;

弊端:多个线程需要判断锁,较为消耗资源。

同步实例:

例1:简单的同步代码块结构

class MyClass implements Runnable{
public void run(){
synchronized (this) {
System.out.println("需要同步的代码");
}
}
}

注:synchronized代码块中锁可以是任意对象。

 例2:多线程操作同一数据(线程功能相同)

class MyClass extends Thread{
private static int x=0;
public void run(){
while(x<=100){
synchronized (Test.class) {
if(x<=100){
System.out.println(Thread.currentThread().getName()+"--"+"x="+x);
x++;
}
}
}
}
}
public class Test {
public static void main(String[] args){
MyClass mc1=new MyClass();
MyClass mc2=new MyClass();
mc1.start();
mc2.start();
}
}
例3:多线程操作同一数据(线程功能不同)
class Resource{
//产品名称,编号,标记
private String name;
private int count = 1;
private boolean flag = false;
//生产者
public synchronized void set(String name){
if(flag)
try{
wait();
}
catch (Exception e){
}
this.name  = name+"--"+count++;
String aa = Thread.currentThread().getName();
String bb = this.name;
System.out.println(aa+"..生产者.."+bb);
flag = true;
this.notify();
}
//消费者
public synchronized void out(){
if(!flag)
try{
wait();
}
catch (Exception e){
}
String aa = Thread.currentThread().getName();
String bb = this.name;
System.out.println(aa+"...消费者.."+bb);
flag = false;
this.notify();
}
}
//生产者类实现Runnable接口
class Producer implements Runnable{
private Resource res;
Producer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.set("商品");
}
}
}
//消费者实现Runnable接口
class Consumer implements Runnable{
private Resource res;
Consumer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.out();
}
}
}
class  ProducerConsumerDemo{
public static void main(String[] args){
Resource r = new Resource();
new Thread(new Producer(r)).start();
new Thread(new Consumer(r)).start();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: