• java学习笔记(8)——多线程


    进程:是一个程序在其自身的地址空间的一次执行活动。
    线程:(区别于进程)线程没有独立的存储空间。
    几个概念:时间片 线程  进程  
    能不能够用多进程代替多线程呢?
    两个进程切换时要交换内存空间,而多线程切换时效率比较高,所以通常多个任务采用多线程,不要开启大量的进程。
    java在语言级别提供了对多线程程序设计的支持
    实现多线程程序的两种方式:
    1,从Thread类继承
    2,实现Runable接口
    ----------------------------------------------------------------------------------
    package pack02;
    //得到main函数的线程名
    public class MultiThread {
    public static void main(String[] args){
    Thread thread = Thread.currentThread();  //得到当前线程
    String string = thread.getName();    //得到线程名
    System.out.println(string);
    }
    }
    ----------------------------------------------------------------------------------
    package pack02;
    //得到线程类的线程名
    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread();
    mt.start();   //启动线程
    }
    }
    class MyThread extends Thread{  //Thread实现了Runable接口
    public void run(){
    System.out.println(getName());  //继承了getName()方法
    }
    }
    ----------------------------------------------------------------------------------
    package pack02;


    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread("i am thread");  //给线程命名
    mt.start();   //启动线程
    }
    }
    class MyThread extends Thread{
    public MyThread(String str){  //调用有参数的构造
    super(str);
    }
    public void run(){
    System.out.println(getName());  //继承了getName()方法
    }
    }
    ----------------------------------------------------------------------------------
     void setDaemon(boolean on) //后台线程
              将该线程标记为守护线程或用户线程。 
    前台线程是可以阻止进程终止的,而后台线程在进程终止后终止。
    ----------------------------------------------------------------------------------
    package pack02;


    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread("i am thread");
    mt.setDaemon(true);  //设为后台线程
    mt.start();   //启动线程
    int i = 0;
    while(true){
    if(i++ == 10000){
    break;
    }
    System.out.println(Thread.currentThread().getName());
    }
    }
    }
    class MyThread extends Thread{
    public MyThread(String str){
    super(str);
    }
    public void run(){
    while(true){
    System.out.println(getName());  //继承了getName()方法
    }
    }
    }
    -----------------------------------------------------------------------------------------
    yeid()方法  :放弃自己执行的权力,让其他线程执行
    ------------------------------------------------------------------------------------
    package pack02;


    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread("i am thread");
    mt.setDaemon(true);  //设为后台线程
    mt.start();   //启动线程
    int i = 0;
    while(true){
    if(i++ == 10000){
    break;
    }
    System.out.println(Thread.currentThread().getName());
    }
    }
    }
    class MyThread extends Thread{
    public MyThread(String str){
    super(str);
    }
    public void run(){
    while(true){
    System.out.println(getName());  //继承了getName()方法
    yield();   //线程休眠
    }
    }
    }
    ---------------------------------------------------------------------------------------
    MAX_PRIORITY(10)  MIN_PRIORITY(1)  NORM_PRIORITY(5)设置线程的优先级
    package pack02;


    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread("i am thread");
    mt.setPriority(Thread.MAX_PRIORITY);
    mt.start();   //启动线程
    int i = 0;
    while(true){
    if(i++ == 10000){
    break;
    }
    System.out.println(Thread.currentThread().getName());
    }
    }
    }
    class MyThread extends Thread{
    public MyThread(String str){
    super(str);
    }
    public void run(){
    while(true){
    System.out.println(getName());  //继承了getName()方法  //线程休眠
    }
    }
    }
    --------------------------------------------------------------------------------
    Java运行时系统实现了一个用于调度线程执行的线程调度器,用于确定某一时刻由哪一个线程在CPU上运行。
    Java中线程是抢占式的而不需要时间片分配进程。
    实现Runnable接口的好处:
    1,实现接口可以实现多个接口和再继承
    2,可以创建多个线程而用同一个属性(变量)
    ------------------------------------------------------------------------------------
    package pack02;


    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread();
    new Thread(mt).start();  //线程1
    new Thread(mt).start();  //线程2
    new Thread(mt).start();  //线程3
    new Thread(mt).start();  //线程4
    int i = 0;
    while(true){
    System.out.println(Thread.currentThread().getName());
    }
    }
    }
    class MyThread implements Runnable{
    int i = 0;  //共用同一个变量
    public void run(){
    while(true){
    System.out.println(Thread.currentThread().getName()+":"+i++);  //继承了getName()方法  //线程休眠
    }
    }
    }
    ------------------------------------------------------------------------------------
    package pack02;
    //内部内实现多线程共用一个变量
    public class MultiThread {
    public static void main(String[] args){
    MyThread mt = new MyThread();
    mt.getTread().start();   //启动线程1
    mt.getTread().start();   //启动线程2
    mt.getTread().start();   //启动线程3
    mt.getTread().start();   //启动线程4
    int i = 0;
    while(true){
    System.out.println(Thread.currentThread().getName());
    }
    }
    }
    class MyThread{
    int i = 0;  //共用同一个变量
    class InnerThread extends Thread{  //写一个内部内实现多线程共用变量
    public void run(){
    while(true){
    System.out.println(getName()+":"+i++);
    }
    }
    }
    Thread getTread(){
    return new InnerThread();
    }
    }
    --------------------------------------------------------------------------------------
    package pack02;
    //火车站订票系统
    public class TicksSystem {
    public static void main(String[] args){
    SellTread st = new SellTread();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    }
    }
    class SellTread implements Runnable{


    int tickets = 100;
    public void run() {
    while(true){
    if(tickets>0){  //这里会出现问题可能售出0,-1,-2,-3的票
    try {
    Thread.sleep(10);  //用于测试
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
    tickets--;
    }
    }

    }

    }
    -----------------------------------------------------------------------------------------
    线程的同步:
    每一个对象都有一把锁子
    同步块
    -----------------------------------------------------------------------------------------
    package pack02;


    public class TicksSystem {
    public static void main(String[] args){
    SellTread st = new SellTread();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    }
    }
    class SellTread implements Runnable{


    int tickets = 100;
    Object obj = new Object();
    public void run() {
    synchronized(obj){  //obj对象拿出了自己的锁子
    while(true){
    if(tickets>0){
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
    tickets--;
    }
    }
    }
    }
    }
    --------------------------------------------------------------------------------------------
    同步方法
    -------------------------------------------------------------------------------------------
    package pack02;


    public class TicksSystem {
    public static void main(String[] args){
    SellTread st = new SellTread();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    new Thread(st).start();
    }
    }
    class SellTread implements Runnable{


    int tickets = 100;
    public void run() {
    while(true){
    sell();
    }
    }
    public synchronized void sell(){ //实际上是给this加锁
    if(tickets>0){
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
    tickets--;
    }
    }
    }
    ----------------------------------------------------------------------------------------------
    每个class也有一个锁,是这个class所对应的Class对象的锁。
    线程的死锁:
    ----------------------------------------------------------------------------------------------
    package pack02;


    public class TicksSystem {
    public static void main(String[] args){
    SellTread st = new SellTread();
    new Thread(st).start();
    try {
    Thread.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    st.flag = true;
    new Thread(st).start();
    }
    }
    class SellTread implements Runnable{
    boolean flag = false;
    int tickets = 100;
    Object obj = new Object();
    public void run() {
    if(flag == true){
    sell();
    }else{
    while(true){
    synchronized(obj){
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    synchronized (this) {
    if(tickets>0){
    System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
    tickets--;
    }
    }
    }
    }
    }
    }
    public synchronized void sell(){
    synchronized (obj) {
    if(tickets>0){
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
    tickets--;
    }
    }
    }
    }
    -------------------------------------------------------------------------------------------------
    wait notify notifyAll  (Object中的方法)
    每一个对象除了有一个锁之外,还有一个等待队列(waitsct),当一个对象刚创建的时候,它的等待队列
    是空的。
    我们应该在当前线程锁住对象的锁后,去调用该对象的wait方法。
    当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可
    运行的线程。
    当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。
    wait和notify主要用于producer-consumer这种关系中。
    ------------------------------------------------------------------------------------------------
    package test;
    //生产者是一个对象
    //消费者是个对象
    //中转站是个对象
    //wait 和 notify 必须放在同步块中或同步方法中(必须是同一个对象)
    //该例子中调用的都是this对象的wait和notify方法
    public class Test {
    public static void main(String[] args){
    Queue queue = new Queue();
    Producer p = new Producer(queue);
    Consumer c = new Consumer(queue);
    p.start();
    c.start();
    }
    }
    class Producer extends Thread{ //生产者
    Queue q;
    public Producer(Queue q) {
    this.q = q;
    }
    public void run(){
    for(int i=0;i<10;i++){
    System.out.println("Producer put" + i);
    q.put(i);
    }
    }
    }


    class Consumer extends Thread{ //消费者
    Queue q;
    public Consumer(Queue q){
    this.q = q;
    }
    public void run(){
    while(true){
    System.out.println("Consumer get" + q.get());
    }
    }
    }
    class Queue{  //中专站
    int value;
    boolean bFull = false;
    public synchronized void put(int i){ //this对象的监视器
    if(!bFull){  //没有数据
    value = i;  //放置数据
    bFull = true; //放过数据
    notify(); //通知消费者获取数据
    }
    try {
    wait(); //等待消费者获取数据
    } catch (InterruptedException e){
    e.printStackTrace();
    }
    }
    public synchronized int get(){
    if(!bFull){  //没有数据
    try {  
    wait(); //等待放数据 
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    bFull = false;  //有数据
    notify();  //通知生产者继续放置数据
    return value;  //得到数据
    }
    }
    --------------------------------------------------------------------------------------------
    线程的状态:

    New--------->Runnable-------slep,wait,suspend,I/O阻塞------------------>Not Runnable

     <------------sleep结束,notify,resume,I/O操作完成---
    终止线程的方法:
    设置一个flag变量终止线程。
    interrupt()方法
    ----------------------------------------------------------------------------------------------
    package test;


    public class Test{
    public static void main(String[] args) {
    Thread1 t1 = new Thread1();
    t1.start();
    int index = 0;
    while(true){
    if(index++ == 500){
    t1.stopThread();
    t1.interrupt(); 
    break;
    }
    System.out.println(Thread.currentThread().getName()+index);
    }
    System.out.println("main exit");
    }
    }


    class Thread1 extends Thread{
    private boolean bStop = false;
    public synchronized void run(){
    while(!bStop){
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    if(bStop) return;
    }
    System.out.println(getName());
    }
    }
    public void stopThread(){
    bStop = true;
    }
    }
    ------------------------------------------------------------------------------------------
    java的语言规范:
    http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html
  • 相关阅读:
    一个简单实现的遮罩层
    文字内容过长是自动出现省略号
    Maven入门学习(下)
    Maven入门学习(上)
    使用ODP.NET查询数据参数顺序问题及莫名ORA-01722错误提示
    Xamarin开发Android笔记:TextView行间距设定
    Xamarin开发Android笔记:图片切换ImageSwitcher
    Xamarin开发Android笔记:背景操作
    UI创意求助:手机贪吃蛇游戏方向控制键设计
    做梦想起来的C#简单实现贪吃蛇程序(LinQ + Entity)
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469947.html
Copyright © 2020-2023  润新知