Java多线程---线程、同步

6 篇文章 0 订阅

Java多线程

线程和进程的区别

可能也就是一个选择题

线程

在于并发concurrent

线程的生命周期
在这里插入图片描述
看图就好了

创建Java线程的方式

通过继承Thread方式实现

1.新建一个类,继承Thread类,这里叫作MyThread
2.完善run方法();执行代码在这里
3.新建MyThread实例
4.start()

   class MyThread extends Thread       //自定义线程类
        {
            public void run()                       //核心方法
            {
                System.out.println("MyThread线程执行");
            }
        }
public  class test
        {
            public static void main(String []args)
            {
                    MyThread myThread=new MyThread();        //创建实例
                    myThread.start();                  //一定要用start,不可用run
            }
通过实现Runnable接口

1.新建一个类,实现Runnable接口
2.重点在于实现run方法。
3.新建一个Runnable类实例
4.新建一个Thread类实例,初始化时传入实现了Runnable的类实例
5.start()

     ....
        {
            public static void main(String []args)
            {
                    MyThread myThread=new MyThread();
                    Thread thread=new Thread(myThread);         //将实现了Runnable的接口的类实例传过去
                    thread.start();
            }
        }

class MyThread implements Runnable          //实现了Runnable接口
{
    public void run()
    {
        System.out.println("线程运行");
    }
}

几个跟线程生命周期相关的方法

yield:当前线程让出,当前线程进入就绪状态,等候重新获取
sleep:当前线程睡眠一段时间,进入阻塞状态,时间到了之后进入就绪状态
join:强制插入,使线程成为运行状态

重点:线程同步

PPT主要讲了synchronized方法。

synchronized

使用方法:
sychronized锁住某段代码块
sychronized锁住某个方法
通过对互斥锁的获取和释放,保证了只有一个线程拥有锁,
只有拥有锁的线程才能执行对应的程序
每个对象都可以作为互斥锁
一般用当前对象

程序执行完会自动释放锁

synchronized(Object )           //同步代码块
{
 }

 public synchronized int getNum()     //同步方法,默认用当前类的实例对象作为锁
 {
 }

线程通信

wait
notify
notifyall
这个比较重实践

总结一下多线程的题目:
1.确定共享变量,尽可能的少 而足
2.定义共享变量(一些状态变量、一些锁)
3.定义一个实现了Runnable的类模板
4.通过参数设置不同的类实例(eg:abc、次数、下一个state)
5.开始start

**可以通过改变state,指定下一个code实现指定的任务启动**

实践

public class test {
   public static volatile int state=0;        //通过类的静态变量实现变量共享、并且是唯一变量

   class printer implements Runnable
   {     //内部类。主要是为了实现
       private int printcode;
       private int nextCode;                   //用于指示下一个状态量
       private Object printLock;            //锁元素
       private int countNum;
       private char printchar;

       public printer(Object printLock, int countNum, int printcode, int nextCode, char printchar)        //通过传入参数,实现不同实例要求
       {
           this.printchar = printchar;
           this.printcode = printcode;
           this.printLock = printLock;
           this.countNum = countNum;
           this.nextCode = nextCode;
       }

       public void run() {        //运行方法
           synchronized (printLock) {         //同步代码段
               for (int i = 0; i < countNum; i++) {

                   try {
                       if (printcode != test.state) {
                           printLock.wait();
                       }
                       else{
                           System.out.println(printchar);
                           test.state = nextCode;
                           printLock.notifyAll();              //一定要是notifyall
                       }
                   } catch (InterruptedException e) {
                       return;
                   }

               }
           }
       }   //内部类结束,内部类是为了能够简单的直接获取state共享变量
   }
   public void tst()
   {
       Object lock=new Object();
       printer pa=new printer(lock,20,0,1,'a');      //各自的实例
       printer pb=new printer(lock,20,1,2,'b');
       printer pc=new printer(lock,20,2,0,'c');
       Thread m1=new Thread(pa);
       Thread m2=new Thread(pb);
       Thread m3=new Thread(pc);
       m1.start();
       m2.start();
       m3.start();
   }

   public static void main(String[]args)            //外部类的main方法
   {
  test t=new test();
  t.tst();
   }
}

另外的一种实现方式是Java的锁lock
ReentrantLock和condition
不建议这么用 ,万一被老师判错
ReentrantLock是一个锁,可以实现跟 synchronized一样的封锁代码段的效果,
需要自己调用lock、unlock加锁解锁

ReentrantLock

方法:
lock() 加锁
unlock()解锁
newCondition() 通过锁产生条件,可以产生有多个条件

Condition

await() 等待,进入阻塞
sinal 通知一个线程解睡眠
sinalAll 通知所有线程解睡眠

// wait 模板,signal 模板
lock.lock();
try{
    // wait 条件:一般都是使用while
    while(meet the condition){
        condition.await();
    }
    // 满足条件进行一系列操作
    ... your operation
    otherCondition.signal()// otherCondition.signalAll()

}catch(){

}finally{
    lock.unlock();
}

好吧,下面代码冗余太多了

import java.io.FileOutputStream;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public  class test
{
    public static void main(String[]args) throws  Exception
    {
        myThreaA a=new myThreaA();
        myThreaB b=new myThreaB();
        myThreaC c=new myThreaC();
        a.start();
        b.start();
        c.start();
    }
}

class Printer
{
    static ReentrantLock lock=new ReentrantLock();         //共享量
    static Condition c1=lock.newCondition();
    static Condition c2=lock.newCondition();
    static Condition c3=lock.newCondition();
    private static volatile int state=0;         //打印机状态
    private int  nowState;                     //实例的编号
    private char nowChar;                     //对应实例的打印内容
    Printer(int State,char c)
    {
        this.nowChar=c;
        this.nowState=State;
    }
    public void printA() throws InterruptedException
    {
        lock.lock();
        if (state!=nowState)
            c1.await();
        System.out.print('a');
        state=(state+1)%3;
        c2.signal();
        lock.unlock();
    }
    public void printC() throws InterruptedException
    {
        lock.lock();
        if (state!=nowState)
            c3.await();
        System.out.println('c');
        state=(state+1)%3;
        c1.signal();
        lock.unlock();
    }
    public void printB() throws InterruptedException
    {
        lock.lock();
        if (state!=nowState)
            c2.await();
        System.out.print('b');
        state=(state+1)%3;
        c3.signal();
        lock.unlock();
    }
}

class myThreaA extends Thread
{
    Printer a=new Printer(0,'a');
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                a.printA();
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}
class myThreaB extends Thread
{
    Printer b=new Printer(1,'b');
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                b.printB();
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}
class myThreaC extends Thread
{
    Printer b=new Printer(2,'c');
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                b.printC();
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值