Java 1类中的同步线程
我一直在寻找一种成功使用多线程和同步的方法。我已经尝试使用wait()和notify(),但我的线程仍然不同步。 我有一个更大的项目,但简而言之,我需要它使用setter方法(在本例中为thread1)运行线程预定次数,在每次“设置”之后,我需要使用getter方法(thread2)运行线程并获取对象。 我已经看过很多其他的例子,但我似乎不能解决它,所以任何帮助或解释为什么这不起作用都将不胜感激 有时,当thread1首先运行时,这是可行的,但有时thread2首先运行,因此同步不起作用 谢谢Java 1类中的同步线程,java,multithreading,wait,synchronized,notify,Java,Multithreading,Wait,Synchronized,Notify,我一直在寻找一种成功使用多线程和同步的方法。我已经尝试使用wait()和notify(),但我的线程仍然不同步。 我有一个更大的项目,但简而言之,我需要它使用setter方法(在本例中为thread1)运行线程预定次数,在每次“设置”之后,我需要使用getter方法(thread2)运行线程并获取对象。 我已经看过很多其他的例子,但我似乎不能解决它,所以任何帮助或解释为什么这不起作用都将不胜感激 有时,当thread1首先运行时,这是可行的,但有时thread2首先运行,因此同步不起作用 谢谢
import java.util.ArrayList;
public class ThreadTest{
private ArrayList<Object> myList;
public ThreadTest(){
myList = new ArrayList<Object>();
Thread thread1 = new Thread(){
public void run(){
for(int i = 0; i < 10; i++){
addToList("" + i);
}
}
};
Thread thread2 = new Thread(){
public void run(){
for(int i = 0; i < 10; i++){
System.out.print(myList.get(i) + " ");
}
}
};
thread1.start();
thread2.start();
}
public synchronized void addToList(String a){
myList.add(a);
notify();
}
public synchronized ArrayList<Object> getList(){
try{
wait();
}
catch (InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
return myList;
}
public static void main(String[] args){
new ThreadTest();
}
}
import java.util.ArrayList;
公共类线程测试{
私人ArrayList myList;
公共线程测试(){
myList=新的ArrayList();
线程thread1=新线程(){
公开募捐{
对于(int i=0;i<10;i++){
地址列表(“+i”);
}
}
};
线程thread2=新线程(){
公开募捐{
对于(int i=0;i<10;i++){
System.out.print(myList.get(i)+“”);
}
}
};
thread1.start();
thread2.start();
}
公共同步的void addToList(字符串a){
添加(a);
通知();
}
公共同步ArrayList getList(){
试一试{
等待();
}
捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回myList;
}
公共静态void main(字符串[]args){
新螺纹试验();
}
}
当您发出通知时,您应该更新一个状态(如您所拥有的),在等待时必须在循环中检查该状态。这是必要的,因为
- 等待开始前的notify触发器,信号丢失
- 等待可能是虚假的
有很多方法可以解决这个问题,但最好的解决方案是使用一个BlockingQueue,它是为支持这个模式而设计的。当你发出通知时,你应该更新一个状态(正如你所做的那样),当你等待时,必须在循环中检查这个状态。这是必要的,因为
- 等待开始前的notify触发器,信号丢失
- 等待可能是虚假的
有很多方法可以解决这个问题,但最好的解决方案是使用BlockingQueue,它是为支持这个模式而设计的。您不应该使用getter和setter来访问整个列表,而应该只从列表中推拉元素。如前所述,
BlockingQueue
是一个同步列表实现
换句话说,如果您想自己实现这一点,请在列表上用一个同步的
remove(0)
替换getList,它只返回ArrayList的第一个元素。您不应该使用getter和setter访问整个列表,而应该只从列表中推拉元素。如前所述,BlockingQueue
是一个同步列表实现
换句话说,如果您想自己实现这一点,请在列表上用一个synchronized
remove(0)
替换getList,它只返回ArrayList的第一个元素。使用BlockingQueue
自动进行同步,使用执行器服务
处理所有线程
public void doStuff() {
final Object finishSupplying = new Object();
final BlockingQueue<Object> myList = new LinkedBlockingQueue<Object>();
final Runnable supplier = new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
myList.add(i);
}
}
};
final Runnable consumer = new Runnable() {
public void run() {
while (true) {
try {
final Object thing = myList.take();
if(thing == finishSupplying) break;
System.out.print(thing + " ");
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
};
final ExecutorService exectutorService = Executors.newFixedThreadPool(2);
final Future<?> supplierHandle = exectutorService.submit(supplier);
final Future<?> consumerHandle = exectutorService.submit(consumer);
try {
supplierHandle.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
//PROBLEMS, handle
}
myList.add(finishSupplying);
try {
consumerHandle.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
//PROBLEMS, handle
}
}
public void doStuff(){
最终对象FinishSuppling=新对象();
final BlockingQueue myList=新建LinkedBlockingQueue();
最终可运行供应商=新可运行供应商(){
公开募捐{
对于(int i=0;i<10;i++){
添加(i);
}
}
};
最终可运行消费者=新可运行(){
公开募捐{
while(true){
试一试{
final Object thing=myList.take();
如果(事物==完成)中断;
系统输出打印(thing+“”);
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}
}
}
};
final ExecutorService ExecutorService=Executors.newFixedThreadPool(2);
最终未来供应商句柄=ExecutorService.submit(供应商);
最终未来消费者handle=executorservice.submit(消费者);
试一试{
supplierHandle.get();
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}捕获(ExecutionException ex){
//问题,处理
}
myList.add(完成供应);
试一试{
consumerHandle.get();
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}捕获(ExecutionException ex){
//问题,处理
}
}
确保
shutdown()
当您完成此操作时,执行器服务将不会退出。使用阻塞队列来自动执行同步,使用执行器服务来处理所有线程
public void doStuff() {
final Object finishSupplying = new Object();
final BlockingQueue<Object> myList = new LinkedBlockingQueue<Object>();
final Runnable supplier = new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
myList.add(i);
}
}
};
final Runnable consumer = new Runnable() {
public void run() {
while (true) {
try {
final Object thing = myList.take();
if(thing == finishSupplying) break;
System.out.print(thing + " ");
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
};
final ExecutorService exectutorService = Executors.newFixedThreadPool(2);
final Future<?> supplierHandle = exectutorService.submit(supplier);
final Future<?> consumerHandle = exectutorService.submit(consumer);
try {
supplierHandle.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
//PROBLEMS, handle
}
myList.add(finishSupplying);
try {
consumerHandle.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
//PROBLEMS, handle
}
}
public void doStuff(){
最终对象FinishSuppling=新对象();
final BlockingQueue myList=新建LinkedBlockingQueue();
最终可运行供应商=新可运行供应商(){
公开募捐{
对于(int i=0;i<10;i++){
添加(i);
}
}
};
最终可运行消费者=新可运行(){
公开募捐{
while(true){
试一试{
final Object thing=myList.take();
如果(事物==完成)中断;
Sy