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
原文地址:https://www.cnblogs.com/lanzhi/p/6469947.html