多线程

多线程

1.创建线程的方式
● 继承Thread。
● 实现Runnable的接口。
2.线程安全问题
当多条语句在操作同一线程共享数据时,一个线程对多条语句只执行了一部分,还没用执行完,另一个线程参与进来执行。导致共享数据的错误。
解决办法:对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
使用同步Synchronized:
synchronized(对象)
        {
   需要被同步的代码
}

示例:多个窗口同事卖票。

package it.practise.com.thread;

public class TicketDemo {
	public static void main(String[] args) {
		Ticket t = new Ticket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		Thread t4 = new Thread(t);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

class Ticket implements Runnable {
	private int tickets = 100;
	Object obj = new Object();
	public void run() {
		while(true) {
			synchronized(obj) {
				if(tickets > 0) {
					System.out.println(Thread.currentThread().getName() + "::" + tickets--);
				}
			}
		}
	}
}




3.生产者消费问题

JDK1.5中提供了多线程升级解决方案。将Synchronized替换成显式的Lock操作。

将Object中的wait, notify, notifyAll,替换成了Condition对象。该对象可以通过Lock获取。

package it.practise.com.thread;


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class ProducerConsumerDemo {


<span style="white-space:pre">	</span>public static void main(String[] args) {
<span style="white-space:pre">		</span>Resource r = new Resource();
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>Producer pro = new Producer(r);
<span style="white-space:pre">		</span>Consumer con = new Consumer(r);
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>Thread t1 = new Thread(pro);
<span style="white-space:pre">		</span>Thread t2 = new Thread(pro);
<span style="white-space:pre">		</span>Thread t3 = new Thread(con);
<span style="white-space:pre">		</span>Thread t4 = new Thread(con);
<span style="white-space:pre">		</span>t1.start();
<span style="white-space:pre">		</span>t2.start();
<span style="white-space:pre">		</span>t3.start();
<span style="white-space:pre">		</span>t4.start();
<span style="white-space:pre">	</span>}


}


class Resource {
<span style="white-space:pre">	</span>private String name;
<span style="white-space:pre">	</span>private int count = 1;
<span style="white-space:pre">	</span>private boolean flag = false;
<span style="white-space:pre">	</span>private Lock lock = new ReentrantLock();
<span style="white-space:pre">	</span>Condition cp = lock.newCondition();
<span style="white-space:pre">	</span>Condition cc = lock.newCondition();
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public void set(String name) throws InterruptedException {
<span style="white-space:pre">		</span>lock.lock();
<span style="white-space:pre">		</span>try{
<span style="white-space:pre">			</span>while(flag)
<span style="white-space:pre">				</span>cp.await();
<span style="white-space:pre">			</span>this.name = name + "--" + count++;
<span style="white-space:pre">			</span>System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
<span style="white-space:pre">			</span>flag = true;
<span style="white-space:pre">			</span>cc.signal();
<span style="white-space:pre">		</span>} finally {
<span style="white-space:pre">			</span>lock.unlock();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public synchronized void out() throws InterruptedException {
<span style="white-space:pre">		</span>lock.lock();
<span style="white-space:pre">		</span>try{
<span style="white-space:pre">			</span>while(!flag)
<span style="white-space:pre">				</span>cc.await();
<span style="white-space:pre">			</span>System.out.println(Thread.currentThread().getName() + "*******消费者*******" + this.name);
<span style="white-space:pre">			</span>flag = false;
<span style="white-space:pre">			</span>cp.signal();
<span style="white-space:pre">		</span>} finally {
<span style="white-space:pre">			</span>lock.unlock();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
}


class Producer implements Runnable {
<span style="white-space:pre">	</span>Resource r = new Resource();
<span style="white-space:pre">	</span>Producer(Resource r) {
<span style="white-space:pre">		</span>this.r = r;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>public void run() {
<span style="white-space:pre">		</span>while(true) {
<span style="white-space:pre">			</span>try {
<span style="white-space:pre">				</span>r.set("商品");
<span style="white-space:pre">			</span>} catch (InterruptedException e) {
<span style="white-space:pre">				</span>e.printStackTrace();
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
}


class Consumer implements Runnable {
<span style="white-space:pre">	</span>Resource r = new Resource();
<span style="white-space:pre">	</span>Consumer(Resource r) {
<span style="white-space:pre">		</span>this.r = r;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>public void run() {
<span style="white-space:pre">		</span>while(true) {
<span style="white-space:pre">			</span>try {
<span style="white-space:pre">				</span>r.out();
<span style="white-space:pre">			</span>} catch (InterruptedException e) {
<span style="white-space:pre">				</span>e.printStackTrace();
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
}




4.线程停止
stop方法已经过时,如何停止线程呢?
只有一种,run方法结束。
开启多线程,通常都是循环结构,只要控制住循环,run方法就可以结束,也就是线程结束。


5.特殊情况:
当线程处于了冻结状态,就不会读取到标记,那么线程就不会结束。
当没有指定的方式让冻结的线程恢复运行状态时,这时需要对冻结进行清除,强制让线程恢复运行状态,这样就可以操作标记,让线程结束。
Thread类提供了该方法 interrupt()


守护线程
void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。


Join方法:
调用该方法的线程会抢夺执行权,其他线程会冻结,直到该线程结束后才会恢复到运行状态。


优先级&yield方法:
优先级一共10级,10最高,默认是5。
yield():暂停当前正在执行的线程对象,并执行其他线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值